正题
P3312
题目大意
给出n,m,a,求∑i=1n∑j=1mσ(gcd(i,j))[σ(gcd(i,j))≤a]\sum_{i=1}^n\sum_{j=1}^m\sigma(gcd(i,j))[\sigma(gcd(i,j))\leq a]i=1∑nj=1∑mσ(gcd(i,j))[σ(gcd(i,j))≤a]
解题思路
先不考虑a的条件限制
∑i=1n∑j=1mσ(gcd(i,j))\sum_{i=1}^n\sum_{j=1}^m\sigma(gcd(i,j))i=1∑nj=1∑mσ(gcd(i,j))
∑d=1nσ(d)∑i=1n/d∑j=1m/d∑c∣i,c∣jμ(c)\sum_{d=1}^n\sigma(d)\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}\sum_{c|i,c|j}\mu(c)d=1∑nσ(d)i=1∑n/dj=1∑m/dc∣i,c∣j∑μ(c)
∑d=1nσ(d)∑c∣i,c∣jμ(c)⌊ncd⌋⌊mcd⌋\sum_{d=1}^n\sigma(d)\sum_{c|i,c|j}\mu(c)\left\lfloor\frac{n}{cd}\right\rfloor\left\lfloor\frac{m}{cd}\right\rfloord=1∑nσ(d)c∣i,c∣j∑μ(c)⌊cdn⌋⌊cdm⌋
设k=cd,枚举k
∑k=1n⌊nk⌋⌊mk⌋∑d∣kσ(d)μ(kd)\sum_{k=1}^n\left\lfloor\frac{n}{k}\right\rfloor\left\lfloor\frac{m}{k}\right\rfloor\sum_{d|k}\sigma(d)\mu(\frac{k}{d})k=1∑n⌊kn⌋⌊km⌋d∣k∑σ(d)μ(dk)
对于后面一部分可以预处理出来
然后整除分块即可
考虑a的限制条件,可以离线处理
先对a进行排序,只计算满足条件的d,对于一段区间的和可以用树状数组
时间复杂度 O(Tnlogn)O(T\sqrt{n}\ log\ n)O(Tn log n)
code
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 100100
#define mod 2147483648
#define mp make_pair
#define fs first
#define sn second
using namespace std;
ll t,w,n,m,ans,now,g[N],f[N],p[N],c[N],qs[N],mu[N],prime[N];
pair<ll,ll>a[N];
struct node
{ll n,m,a,v;
}q[N];
bool cmp(node a,node b)
{return a.a<b.a;
}
void work()
{mu[1]=f[1]=1;for(ll i=2;i<=1e5;++i){if(!p[i]){prime[++w]=i;mu[i]=-1;f[i]=i+1;g[i]=i+1;}for(ll j=1;j<=w&&i*prime[j]<=1e5;++j){p[i*prime[j]]=1;if(i%prime[j]==0){g[i*prime[j]]=g[i]*prime[j]+1;f[i*prime[j]]=f[i]/g[i]*g[i*prime[j]];}else{mu[i*prime[j]]=-mu[i];g[i*prime[j]]=prime[j]+1;f[i*prime[j]]=f[i]*g[i*prime[j]];}}}for(ll i=1;i<=1e5;++i)a[i]=mp(f[i],i);sort(a+1,a+1+100000);return;
}
void add(ll x,ll y)
{for(;x<=1e5;x+=x&-x)(c[x]+=y)%=mod;return;
}
ll ask(ll x)
{ll sum=0;for(;x;x-=x&-x)(sum+=c[x])%=mod;return sum;
}
int main()
{scanf("%lld",&t);for(ll i=1;i<=t;++i){scanf("%lld%lld%lld",&q[i].n,&q[i].m,&q[i].a);q[i].v=i;}sort(q+1,q+1+t,cmp);work();now=1;for(ll i=1;i<=t;++i){while(now<=1e5&&a[now].fs<=q[i].a){for(ll j=1;a[now].sn*j<=1e5;++j)add(a[now].sn*j,(a[now].fs*mu[j]%mod+mod)%mod);now++;}ans=0;n=q[i].n;m=q[i].m;for(ll l=1,r=0;l<=min(n,m);l=r+1){r=min(n/(n/l),m/(m/l));(ans+=(ask(r)-ask(l-1)+mod)%mod*(n/l)%mod*(m/l)%mod)%=mod;}qs[q[i].v]=ans;}for(int i=1;i<=t;++i)printf("%lld\n",qs[i]);return 0;
}