bzoj 1257: [CQOI2007]余数之和sum 数论
1257: [CQOI2007]余数之和sum
Time Limit: 1 Sec Memory Limit: 256 MB
题目连接
http://www.lydsy.com/JudgeOnline/problem.php?id=1257Description
给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod i表示k除以i的余数。例如j(5, 3)=3 mod 1 + 3 mod 2 + 3 mod 3 + 3 mod 4 + 3 mod 5=0+1+0+3+3=7
Input
输入仅一行,包含两个整数n, k。
Output
输出仅一行,即j(n, k)。
Sample Input
5 3
Sample Output
7
HINT
50%的数据满足:1<=n, k<=1000 100%的数据满足:1<=n ,k<=10^9
题意
题解:
数学题先打表,然后我们就可以得到一个规律,在k/l==k/r的这个范围内,模数是一个等差数列知道这个性质之后,我们就可以二分来搞定对于每一个k/l的结尾,然后再搞一搞就好了
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 200001 #define mod 10007 #define eps 1e-9 //const int inf=0x7fffffff; //无限大 const int inf=0x3f3f3f3f; /* inline ll read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int buf[10]; inline void write(int i) { int p = 0;if(i == 0) p++; else while(i) {buf[p++] = i % 10;i /= 10;} for(int j = p-1; j >=0; j--) putchar('0' + buf[j]); printf("\n"); } */ //************************************************************************************** int main() { ll n,k; cin>>n>>k; //for(int i=1;i<=m;i++) // cout<<n%i<<endl; ll now=1; ll ans=0; while(now<=n) { ll l=now,r=n+1; while(l+1<r) { ll m=(l+r)/2; if((int)(k/m)==(int)(k/now)) l=m; else r=m; } ans+=(l-now+1)*(k%now+k%l)/2; now=l+1; } cout<<ans<<endl; }