[BZOJ 2820]YY的GCD
题目
神犇YY虐完数论后给傻×kAc出了一题给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对kAc这种傻×必然不会了,于是向你来请教……多组输入INPUT
第一行一个整数T 表述数据组数接下来T行,每行两个正整数,表示N, M
OUTPUT
T行,每行一个整数表示第i组数据的结果
SAMPLE
INPUT
2
10 10
100 100
OUTPUT
30
2791
解题报告
反演首题(说好NOIP不考反演的QAQ,最近考了这么多QAQ)
设$nleqslant m$
$$sum_{isprime(p)} sum_{a=1}^{n} sum_{b=1}^{m}gcd(a,b)==p$$
$$sum_{isprime(p)} sum_{a=1}^{left lfloor frac{n}{p} ight floor} sum_{b=1}^{left lfloor frac{m}{p} ight floor}gcd(a,b)==1$$
$$sum_{isprime(p)} sum_{a=1}^{left lfloor frac{n}{p} ight floor} sum_{b=1}^{left lfloor frac{m}{p} ight floor} sum_{dmid gcd(a,b)} mu (d)$$
$$sum_{isprime(p)} sum_{a=1}^{left lfloor frac{n}{p} ight floor} sum_{b=1}^{left lfloor frac{m}{p} ight floor} sum_{dmid awedge dmid b} mu (d)$$
$$sum_{isprime(p)}sum_{d=1}^{left lfloor frac{n}{p} ight floor}mu (d)left lfloor frac{n}{pd} ight floor left lfloor frac{m}{pd} ight floor$$
设$k=pd$
$$sum_{k=1}^{n}sum_{isprime(p)wedge pmid k}mu (frac{k}{p})left lfloor frac{n}{k} ight floor left lfloor frac{m}{k} ight floor$$
$$sum_{k=1}^{n}F(k)left lfloor frac{n}{k} ight floor left lfloor frac{m}{k} ight floor$$
woc,我tm写了点啥
然后就线性筛一下,可以GG
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 inline int read(){ 6 int sum(0); 7 char ch(getchar()); 8 for(;ch<'0'||ch>'9';ch=getchar()); 9 for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar()); 10 return sum; 11 } 12 typedef long long L; 13 int t,n,m; 14 bool isnotprime[10000005]; 15 int prime[10000005],mu[10000005],num; 16 L f[10000005]; 17 inline void play_table(){ 18 mu[1]=1; 19 for(int i=2;i<=10000000;++i){ 20 if(!isnotprime[i]){ 21 prime[++num]=i; 22 mu[i]=-1; 23 } 24 for(int j=1;j<=num&&i*prime[j]<=10000000;++j){ 25 isnotprime[i*prime[j]]=1; 26 if(i%prime[j]==0){ 27 mu[i*prime[j]]=0; 28 break; 29 } 30 else 31 mu[i*prime[j]]=-mu[i]; 32 } 33 } 34 for(int i=1;i<=num;++i){ 35 int p(prime[i]); 36 for(int j=1;j*p<=10000000;++j) 37 f[j*p]+=mu[j]; 38 } 39 for(int i=1;i<=10000000;++i) 40 f[i]+=f[i-1]; 41 } 42 inline int gg(){ 43 freopen("YYnoGCD.in","r",stdin); 44 freopen("YYnoGCD.out","w",stdout); 45 play_table(); 46 t=read(); 47 while(t--){ 48 L ans(0); 49 n=read(),m=read(); 50 if(n>m) 51 swap(n,m); 52 for(int i=1,j;i<=n;i=j+1){ 53 j=min(n/(n/i),m/(m/i)); 54 ans+=(f[j]-f[i-1])*(n/i)*(m/i); 55 } 56 printf("%lld ",ans); 57 } 58 return 0; 59 } 60 int K(gg()); 61 int main(){;}