hdu2620 Ice Rain(数论分块)

北慕城南 提交于 2019-12-22 14:23:59

题意:
Given two integers n,k(1<=n,k<=109).Given \ two \ integers\ n, k(1 <= n, k <= 109).,求
在这里插入图片描述
思路:数论分块。
i=1nk%i\sum_{i=1}^nk \% i
=i=1n(kkii)=\sum_{i=1}^{n}(k - \left\lfloor\\\tfrac{k}{i}\right\rfloor*i)

=nki=1n(kii)=n*k-\sum_{i=1}^{n}(\left\lfloor\\\tfrac{k}{i}\right\rfloor*i)
有数论分块可得,
对于每一个ll,有一个对应的右端点nnl\dfrac{n}{\left\lfloor\\\tfrac{n}{l}\right\rfloor},在这个区间[l,r][l,r]中的值都是nl\dfrac{n}{l}
故上述[1,n][1,n]的区间可以划分为多个小区间,每个小区间ki\left\lfloor\\\tfrac{k}{i}\right\rfloor的值都相等。
故令t=kit=\left\lfloor\\\tfrac{k}{i}\right\rfloor
那么
nki=1n(kii)n*k-\sum_{i=1}^{n}(\left\lfloor\\\tfrac{k}{i}\right\rfloor*i)

=nk(tlri)=n*k-\sum(t*\sum_{l}^{r}i)
AC Code:AC \ Code:

#include<iostream>
#include<cstring>
#include<queue>
#include<map>
#include<cmath>
#include<set>
#include<stack>
#include<cstdio>
#include<sstream>
#include<vector>
#include<bitset>
#include<algorithm>

using namespace std;
#define read(x) scanf("%d",&x)
#define Read(x,y) scanf("%d%d",&x,&y)
#define gc(x)  scanf(" %c",&x);
#define mmt(x,y)  memset(x,y,sizeof x)
#define write(x) printf("%d\n",x)
#define pii pair<int,int>
#define INF 0x3f3f3f3f 
#define ll long long
const int N = 100000 + 100;
const int M = 1e6 + 1005;
typedef long long LL;
 
int main(){
    ll  n,m;
    while(cin>>n>>m){
        ll ans = m * n;
        n = min(n,m);
        for(ll l = 1,r = 0;l <= n;l = r + 1){
            r = m/(m/l);
            if(r > n)  r = n;
            ll tmp = m/l *(l + r)*(r - l + 1)/2;
            ans -= tmp;
        }
        cout<<ans<<endl;
    }
   
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!