P2424 约数和
Solution
说实在的评蓝有点过了。。。
数据较大,直接暴力 \(O(n\sqrt{n})\) 复杂度直接起飞。
问题是求 \(f(x)\) 加到 \(f(y)\),我们考虑换个思路,把式子变成:
\[\sum_{i=1}^yf(i)-\sum_{i=1}^{x-1}f(i)
\]
即求 \(1\) 到 \(y\) 的约数和减去 \(1\) 到 \(x-1\) 的约数和。
现在问题变成了怎么求 \(1\) 到 \(n\) 的约数和。考虑每个约数对答案的贡献,在 \([1,n]\) 内,含有 \(i\) 因数的数的个数为 \(\lfloor \frac ni\rfloor\),所以就是:
\[\sum_{i=1}^ni\lfloor \frac ni\rfloor
\]
然后这个式子整除分块随便搞,就写完了。
Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
void read(int &x)
{
char ch=getchar();
int r=0,w=1;
while(!isdigit(ch))w=ch=='-'?-1:1,ch=getchar();
while(isdigit(ch))r=(r<<3)+(r<<1)+(ch^48),ch=getchar();
x=r*w;
}
main()
{
int x,y;
read(x);read(y);
x-=1;
int sum1=0;
for(int i=1,j;i<=x;i=j+1)
{
j=(x/(x/i));
sum1+=(x/i)*(i+j)*(j-i+1)/2;
}
int sum2=0;
for(int i=1,j;i<=y;i=j+1)
{
j=(y/(y/i));
sum2+=(y/i)*(i+j)*(j-i+1)/2;
}
cout<<sum2-sum1;
return 0;
}