P2261 [CQOI2007]余数求和
作者:互联网
分析
求的式子为\(ans = \sum_{i=1}^{n} k\%i\),我们首先需要知道的是\(a\%b=a-b*\left \lfloor \frac{a}{b} \right \rfloor\),则式子就变成了。
\[ans = n*k -\sum_{i=1}^{n}i*\left \lfloor \frac{k}{i} \right \rfloor \]然后\(\left \lfloor \frac{k}{i} \right \rfloor\),可以用整数分块做,这样时间复杂度就降到\(\sqrt{k}\)
中间有一些小的限制,我会在代码中写出来。
Ac_code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int g(int x,int l)//边界为x,该块边界为l
{
return x/(x/l);
}
int main()
{
int n,k;cin>>n>>k;
LL ans = 0;
if(n>k)
{
ans += 1ll*(n-k)*k;
n = k;
}
ans += 1ll*n*k;
for(int l=1,r;l<=n;l=r+1)
{
r = min(g(k,l),n);
ans -= 1ll*(l+r)*(r-l+1)/2*(k/l);
}
cout<<ans<<'\n';
return 0;
}
标签:lfloor,right,frac,int,P2261,rfloor,ans,余数,CQOI2007 来源: https://www.cnblogs.com/aitejiu/p/16656475.html