参考博客https://blog.youkuaiyun.com/qkoqhh/article/details/82180994
OIer的题不好玩呀,不过真是佩服这些大佬们。
注意init初始化的时候,for不能直接开到maxn,按理说不会啊,但确实是T了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=20101009;
const int maxn=1e7+10;
bool vis[maxn];
int prime[maxn];
ll pre[maxn],g[maxn],inv[5];
int n,m;
void init(){
inv[1]=1,g[1]=1,pre[1]=1;
int tot=0;
for(int i=2;i<=n;i++){
if(!vis[i]){
prime[tot++]=i;
g[i]=1-i;
}
for(int j=0;j<tot;j++){
if(i*prime[j]>n){
break;
}
vis[i*prime[j]]=1;
if(i%prime[j]==0){
g[i*prime[j]]=g[i];
break;
}else{
g[i*prime[j]]=g[i]*(1-prime[j]);
}
}
pre[i]=(pre[i-1]+1ll*g[i]*i%mod+mod)%mod;
}
for(int i=2;i<=4;i++){
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
}
int main(){
scanf("%d%d",&n,&m);
ll ans=0;
if(n>m) swap(n,m);
init();
for(int l=1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
if(r>n) r=n;
ans+=(pre[r]-pre[l-1]+mod)%mod*inv[4]%mod*(n/l)%mod*(m/l)%mod*(n/l+1)%mod*(m/l+1)%mod;
ans%=mod;
}
printf("%lld\n",ans);
return 0;
}