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 }

你可能感兴趣的:(Prim)