题解 P1829 【[国家集训队]Crash的数字表格 / JZPTAB】
安利blog
传送门
小学数论知识:
以下规定
套路枚举
套路枚举
套路枚举
设
这个
我们求的就成了
又可以整除分块了。
整除分块套整除分块复杂度是
然后发现了一个有趣的东西:
暴力计算
设
经过计算在
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#define maxn 10000001
#define inf 0x3f3f3f3f
const int mod = 20101009;
using namespace std;
inline int read(){
int x=0,y=0;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')y=1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return y?-x:x;
}
int mu[maxn],sum[maxn],psum[maxn],prime[maxn>>3],cnt;
bool is[maxn];
inline int f(int n,int m){
if(n>m)swap(n,m);
int ans=0;
for(register int l=1,r;l<=n;l=r+1){
r=min(n,min(n/(n/l),m/(m/l)));
(ans+=1ll*(psum[r]-psum[l-1])*sum[n/l]%mod*sum[m/l]%mod)%=mod;
}
return ans;
}
int main(){
mu[1]=is[1]=sum[1]=psum[1]=1;
for(register int i=2;i<maxn;++i){
if(!is[i])prime[++cnt]=i,mu[i]=-1;
sum[i]=(sum[i-1]+i)%mod,psum[i]=(psum[i-1]+1ll*i*i*mu[i]%mod)%mod;
for(register int j=1;j<=cnt&&i*prime[j]<maxn;++j){
is[i*prime[j]]=1;
if(i%prime[j]==0){mu[i*prime[j]]=0;break;}
mu[i*prime[j]]=-mu[i];
}
}
int n=read(),m=read(),ans=0;
if(n>m)swap(n,m);
for(register int l=1,r;l<=n;l=r+1){
r=min(n,min(n/(n/l),m/(m/l)));
(ans+=1ll*(sum[r]-sum[l-1])*f(n/l,m/l)%mod)%=mod;
}
printf("%d\n",(ans+mod)%mod);
}