Crash的數字表格
題解
很明顯的一道莫比烏斯板子題。
原式
設,
反演可得
可得,
令
這樣就可以分塊計算了。
源碼
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define MAXN 10000010
typedef long long LL;
#define int LL
const int INF=0x7f7f7f7f;
const int mo=20101009;
typedef pair<int,int> pii;
#define gc() getchar()
template<typename _T>
void read(_T &x){
_T f=1;x=0;char s=gc();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=gc();}
while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=gc();}
x*=f;
}
int mobius[MAXN],prime[MAXN],cntp;
bool oula[MAXN];
void init(int n){
mobius[1]=1;
for(int i=2;i<=n;i++){
if(!oula[i])prime[++cntp]=i,mobius[i]=mo-i+1;
for(int j=1;j<=cntp&&i*prime[j]<=n;j++){
oula[i*prime[j]]=1;
if(i%prime[j])mobius[i*prime[j]]=mobius[i]*mobius[prime[j]]%mo;
else{mobius[i*prime[j]]=mobius[i];break;}
}
}
for(int i=1;i<=n;i++)mobius[i]=mobius[i]*i%mo;
for(int i=1;i<=n;i++)mobius[i]=(mobius[i]+mobius[i-1])%mo;
}
int S(int n){return n*(n+1)/2%mo;}
int n,m,ans;
signed main(){
read(n);read(m);if(n>m)swap(n,m);init(n);
for(int l=1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
ans=(ans+(mobius[r]-mobius[l-1]+mo)%mo*S(n/l)%mo*S(m/l)%mo)%mo;
}
printf("%lld\n",ans);
return 0;
}