HDU 4135 Co-prime(容斥原理)
算是裸裸的模版题了,求a - b上 和 n互质的数,可是做的很费劲啊,有个地方没用__int64,让我DEBUG了好久。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <map> 5 using namespace std; 6 #define ll __int64 7 #define N 35000 8 int o[N],prim[10000],num; 9 ll judge(ll x, ll n) 10 { 11 int i,j,len; 12 int key[1001]; 13 len = 0; 14 for(i = 1;i <= num-1;i ++)//这里也可以放到主函数里,重复算了。 15 { 16 if(n%prim[i] == 0) 17 { 18 key[len++] = prim[i]; 19 while(n%prim[i] == 0) 20 n = n/prim[i]; 21 } 22 if(n == 1) break; 23 } 24 if(n != 1) key[len++] = n; 25 int q; 26 ll sum,ans = 0; 27 for(i = 1;i < 1<<len;i ++)//状态压缩 28 { 29 q = 0; 30 sum = 1; 31 for(j = 0;j <= len-1;j ++) 32 { 33 if(i&(1<<j)) 34 { 35 sum *= key[j]; 36 q ++; 37 } 38 } 39 if(q&1)//奇数加偶数减 40 ans += x/sum; 41 else 42 ans -= x/sum; 43 } 44 return ans; 45 } 46 int main() 47 { 48 int i,j,len; 49 ll a,b,n; 50 len = (int)sqrt(N*1.0); 51 for(i = 2; i <= len; i ++) 52 { 53 if(!o[i]) 54 { 55 for(j = i+i; j <= N; j += i) 56 { 57 o[j] = 1; 58 } 59 } 60 } 61 num = 1; 62 for(i = 2;i <= N;i ++) 63 { 64 if(!o[i]) 65 prim[num++] = i; 66 } 67 int t; 68 scanf("%d",&t); 69 for(i = 1;i <= t;i ++) 70 { 71 scanf("%I64d%I64d%I64d",&a,&b,&n); 72 printf("Case #%d: ",i); 73 printf("%I64d\n",(b-judge(b,n))-(a-1-judge(a-1,n))); 74 } 75 return 0; 76 }