http://www.lydsy.com/JudgeOnline/problem.php?id=2820
推一波式子
$$\sum_{isprime(p)}\sum_{a=1}^n\sum_{b=1}^mgcd(a,b)==p$$
$$\sum_{isprime(p)}\sum_{a=1}^{\left \lfloor \frac{n}{p} \right\rfloor}\sum_{b=1}^{\left \lfloor \frac{m}{p} \right \rfloor}gcd(a,b)==1$$
$$\sum_{isprime(p)}\sum_{a=1}^{\left \lfloor \frac{n}{p} \right \rfloor}\sum_{b=1}^{\left \lfloor \frac{m}{p} \right \rfloor}\sum_{d|gcd(a,b)}\mu(d)$$
$$\sum_{isprime(p)}\sum_{a=1}^{\left \lfloor \frac{n}{p} \right \rfloor}\sum_{b=1}^{\left \lfloor \frac{m}{p} \right \rfloor}\sum_{d|a \land d|b}\mu(d)$$
$$\sum_{isprime(p)}\sum_{d=1}^{\left \lfloor \frac{n}{p}\right \rfloor}\mu(d){\left\lfloor\frac{n}{pd}\right\rfloor}{\left\lfloor \frac{m}{pd} \right \rfloor}$$
将pd设为k
$$\sum_{k=1}^{n}\sum_{isprime(p) \land p|k}\mu(\frac{k}{p}){\left \lfloor \frac{n}{k} \right \rfloor}{\left \lfloor \frac{m}{k} \right \rfloor}$$
$$\sum_{k=1}^{n}F(k){\left \lfloor\frac{n}{k}\right\rfloor}{\left \lfloor \frac{m}{k} \right \rfloor}$$
就可以线性筛处理F了
#include<cstdio> #include<algorithm> #define maxn 10000007 #define LL long long LL x,y; int n,prime[maxn],miu[maxn],cnt,f[maxn],sum[maxn]; bool v[maxn]; void get_pre() { miu[1]=1; for(int i=2;i<=maxn-7;i++) { if(!v[i]) { v[i]=true;prime[++cnt]=i; miu[i]=-1;f[i]=1; } for(int j=1;j<=cnt;j++) { if(i*prime[j]>maxn-7) break; v[i*prime[j]]=true; if(i%prime[j]==0) { miu[i*prime[j]]=0; f[i*prime[j]]=miu[i]; break; } miu[i*prime[j]]=-miu[i]; f[i*prime[j]]=miu[i]-f[i]; } } for(int i=1;i<=maxn-7;i++) sum[i]=sum[i-1]+f[i]; } int main() { get_pre(); scanf("%d",&n); while(n--) { scanf("%lld%lld",&x,&y); LL k=std::min(x,y),j,ans=0; for(LL i=1;i<=k;i=j+1) { j=std::min(x/(x/i),y/(y/i)); ans+=(x/i)*(y/i)*(sum[j]-sum[i-1]); } printf("%lld\n",ans); } return 0; }