标签:
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7026 Accepted Submission(s):
2584
1 设f(k)为gcd(x,y)=k的数对(x,y)的对数,我们要求的是f(1) 2 设F(k)为gcd(x,y)为k的倍数的数对(x,y)的对数,可以想到F(k)=floor(b/k)*floor(d/k),
F(k)=E[b/k]*[d/k]*mu[k];
3 由莫比乌斯反演得: 4 令lim=min(b/k,d/k) 5 f(1)=mu[1]*F(1) + mu[2]*F[2] + ... + mu[lim]*F(lim) 6 因为(n1,n2)和(n2,n1)算为同一种情况,所以最后结果还要减掉重复的情况。
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #define _llint long long 7 using namespace std; 8 const int maxn=100010; 9 bool jud[maxn]; 10 int mu[maxn] , prime[maxn]; 11 12 void Mobius(){ 13 int cnt=0; 14 memset(jud , 0 , sizeof jud); 15 mu[1]=1; //d=1 16 for(int i=2 ; i<maxn ;i++){ 17 18 if(!jud[i]){ 19 mu[i]=-mu[1]; //1*p 20 prime[cnt++]=i; 21 } 22 for(int j=0 ; j<cnt&&i*prime[j]<maxn ; j++ ){ 23 24 jud[i*prime[j]]=1; 25 if(i%prime[j]==0){ 26 mu[i*prime[j]]=0 ; //²»ÊÇ»¥ÒìµÄËØÊý 27 break; 28 }else{ 29 mu[i*prime[j]]= -1*mu[i]; 30 } 31 } 32 } 33 return ; 34 } 35 36 _llint solve(int n, int m){ 37 38 _llint res=0; 39 for(int i=1; i<=n ;i++){ 40 res+=(_llint)(m/i)*(n/i)*mu[i]; 41 } 42 return res; 43 } 44 45 int main() 46 { 47 int T,a,b,c,d,k; 48 Mobius(); 49 scanf("%d",&T); 50 for(int i=1 ;i<=T ;i++){ 51 scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); 52 if(0==k) 53 { 54 printf("Case %d: 0\n",i); 55 continue; 56 } 57 b/=k , d/=k; 58 if(b>d) swap( b , d ); 59 _llint ans1=solve(b,d); 60 _llint ans2=solve(b,b); 61 printf("Case %d: %lld\n",i,ans1-ans2/2); 62 } 63 return 0; 64 }
标签:
原文地址:http://www.cnblogs.com/gongxijun/p/4581954.html