t<=10000组询问:有多少x,y,满足$xepsilon [1,n],yepsilon [1,m],(x,y)为质数$。n,m<=1e7。
首先式子列出来,f(i)--1<=x<=n,1<=y<=m中有多少(x,y)=i,g(i)--1<=x<=n,1<=y<=m中有多少i|(x,y),$g(i)=sum_{i|d} f(d) ------> f(i)=sum_{i|d} mu(frac{d}{i})g(d)$,而$g(i)=frac{n}{i}frac{m}{i}$,因此$f(i)=sum_{i|d} mu(frac{d}{i})frac{n}{d}frac{m}{d}$,而(x,y)=k的充要条件是(x/k,y/k)=1,因此答案就$ans=sum_{p是质数}^{min(n,m)}sum_{d=1}^{min(n,m)}mu(d)frac{n}{pd}frac{m}{pd}=sum_{t=1}^{min(n,m)}frac{n}{t}frac{m}{t}sum_{p|t}mu(frac{t}{p})$
前面那个sigma可以根号解决,而后面那个东西只跟t有关,因此预处理下即可。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 //#include<bitset> 6 #include<algorithm> 7 //#include<cmath> 8 using namespace std; 9 10 int T,n,m; 11 #define maxn 10000011 12 int miu[maxn],prime[maxn],lp,summiu[maxn]; bool notprime[maxn]; 13 void pre(int n) 14 { 15 lp=0; miu[1]=1; summiu[1]=0; 16 for (int i=2;i<=n;i++) 17 { 18 if (!notprime[i]) {prime[++lp]=i; miu[i]=-1;} 19 for (int j=1;j<=lp && 1ll*prime[j]*i<=n;j++) 20 { 21 notprime[i*prime[j]]=1; 22 if (i%prime[j]) miu[i*prime[j]]=-miu[i]; 23 else {miu[i*prime[j]]=0; break;} 24 } 25 } 26 for (int i=1;i<=lp;i++) 27 for (int j=prime[i],cnt=1;j<=n;j+=prime[i],cnt++) 28 summiu[j]+=miu[cnt]; 29 for (int i=1;i<=n;i++) summiu[i]+=summiu[i-1]; 30 } 31 32 #define LL long long 33 int main() 34 { 35 pre(10000001); 36 scanf("%d",&T); 37 while (T--) 38 { 39 scanf("%d%d",&n,&m); 40 LL ans=0; 41 for (int i=1,to=min(n,m),last;i<=to;i=last+1) 42 { 43 last=min(n/(n/i),m/(m/i)); 44 ans+=1ll*(n/i)*(m/i)*(summiu[last]-summiu[i-1]); 45 } 46 printf("%lld ",ans); 47 } 48 return 0; 49 }