神犇YY虐完數論後給傻×kAc出了一題html
給定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)爲質數的(x, y)有多少對ios
kAc這種傻×必然不會了,因而向你來請教……git
多組輸入spa
第一行一個整數T 表述數據組數code
接下來T行,每行兩個正整數,表示N, Mhtm
T行,每行一個整數表示第i組數據的結果blog
2ip
10get
10input
100
100
30
2791
\(T \leq 10000\)
\(N, M \leq 10000000\)
簡單版:【BZOJ2818】Gcd
如下式子從【BZOJ2818】Gcd最後一步開始化。
(注:式子中\(d\)默認爲質數)
\[ \begin{split} ans&=\sum\limits_{d=1}^n\sum\limits_{i=1}^{\lfloor\frac nd\rfloor}\mu(i)\lfloor\frac n{id}\rfloor\lfloor\frac m{id}\rfloor\\ 設T&=id\\ ans&=\sum\limits_{d=1}^n\sum\limits_{d|T}^n\mu(\frac Td)\lfloor\frac nT\rfloor\lfloor\frac mT\rfloor\\ &=\sum\limits_{T=1}^n\sum\limits_{d|T}\mu(\frac Td)\lfloor\frac nT\rfloor\lfloor\frac mT\rfloor\\ &=\sum\limits_{T=1}^n\lfloor\frac nT\rfloor\lfloor\frac mT\rfloor\sum\limits_{d|T}\mu(\frac Td) \end{split} \]
對於後面的\(\sum\limits_{d|T}\mu(\frac Td)\),
咱們能夠選擇\(O(n\log n)\)的調和級數方法預處理,
也能夠根據其積性在線性篩中預處理。
以後,即可以整除分塊直接\(O(\sqrt n)\)計算。
#include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<cstdio> #include<iomanip> #include<cstdlib> #define MAXN 0x7fffffff typedef long long LL; const int N=1e7+5; using namespace std; inline int Getint(){register int x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;} int mu[N],prime[N],g[N]; bool vis[N]; int main(){ mu[1]=1; for(int i=2;i<=1e7;i++){ if(!vis[i])prime[++prime[0]]=i,mu[i]=-1,g[i]=1; for(int j=1;j<=prime[0]&&1ll*i*prime[j]<=1e7;j++){ vis[i*prime[j]]=1; if(i%prime[j]==0){ g[i*prime[j]]=mu[i]; break; } mu[i*prime[j]]=-mu[i]; g[i*prime[j]]=mu[i]-g[i]; } } for(int i=2;i<=1e7;i++)g[i]+=g[i-1]; int T=Getint(); while(T--){ int n=Getint(),m=Getint(); if(n>m)swap(n,m); LL ans=0; for(int l=1,r;l<=n;l=r+1){ r=min(n/(n/l),m/(m/l)); ans+=1ll*(n/l)*(m/l)*(g[r]-g[l-1]); } cout<<ans<<'\n'; } return 0; }