题目:
题意:
给定n, k,求出∑ni=1(k modi )
分析:
这题不难,但是我一直WA了七次,我的思路跟书上的是一样的,一直找错误,一直WA,但一直找不到我哪里错了,后来无奈,看了刘汝佳的代码,他实现起来没有讨论k和n谁小谁大,直接比较的,而我先讨论了,n>=k的情况(因为这时候,对于所有的i>k,ans都要加上k),然后再用等差公式求解n<k的情况,思路是对的,但是我没有考虑到(n-k)*k会溢出,所以WA了好多次,所以写下了为以后提个醒。
看个例子n=10,k=8;
求和i从1到n: 0 0 2 0 3 2 1 0 8 8
可以看出,对于i>k,以后的所有数,都是+8,对于i<K的数,其中有一个明显的规律,3 2 1 0这是一个等差数列,d=-1,而1==k/i(i为5 6 7 8),整段长度处在2个0之间,也就是k可以整除的2个数之间,所以根据这个规律就可求了。具体参考代码。
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int main()
{
int n,k;
while(~scanf("%d%d",&n,&k)){
ll ans=0;
if(n>k)ans=(ll)(n-k)*k,n=k-1; //这里要注意,会爆int,完全没考虑到这里。。
int i=1,j;
while(i<=n){
int p=k/i;
int m=k%i;
if(m==0){
i++;continue;
}
j=k/p; //j是k的整除位置
if(j>n)j=n;
int num=j-i+1;
ans+=(ll)num*m-(ll)num*(num-1)/2*p; //等差数列公式n*a1+(n)*(n-1)/2*d
i=j+1;
}
cout<<ans<<endl;
}
return 0;
}