您的位置:首页 > 其它

[BZOJ1257][CQOI2007]余数之和sum

2015-07-20 17:46 393 查看
{原题地址](http://www.lydsy.com/JudgeOnline/problem.php?id=1257)

求∑ni=1k mod i,其中i为整数且i∈[1,n].

1≤n,k≤109

粗略地写一下做法:

将所求式子变形得

∑ni=1k mod i=nk−∑ni=1[ki]

注意到当i∈[1,k√]时,ki∈[k√,k],这一段枚举i暴力即可;

当i∈[k√,k]时,ki∈[1,k√],这一段枚举k的取值,再二分i即可.

细节较多,但好在容易验证答案…

AC code:

#include <cstdio>
#include <cmath>
typedef long long ll;
ll n,k,m,ans;

int main(){
scanf("%lld%lld",&n,&k);
m=(ll)sqrt(k);
if(n<=m){
for(ll i=1;i<=n;i++) ans+=k%i;
printf("%lld",ans);
return 0;
}
ans=n*k;
for(ll i=1;i<=m;i++) ans-=i*(k/i);
ll L=m+1,R=n;
while((k/L)==(k/m)&&L<=R){
ans-=L*(k/L);
L++;
}
if(L==R+1){
printf("%lld",ans);
return 0;
}
for(ll i=k/L;i>0;i=k/L){
ll l=L-1,r=R+1;
while(l+1!=r){
ll mid=(l+r)>>1;
if(k/mid==i) l=mid;
else r=mid;
}
if(r==L) break;
ans-=(((l+L)*(l-L+1))>>1)*i;
L=l+1;
if(L==R+1) break;
}
printf("%lld",ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: