【容斥】HDU 4135 Co-prime

acm.hdu.edu.cn/showproblem.php?pid=4135

【题意】

  • 询问[a,b]中与n互质的数有多少个

【思路】

  • 考虑[1,m]中与n互质的数有多少个,答案就是query(b)-query(a-1)
  • 正难则反,考虑[1,m]中与n不互质的数有多少个
  • 求出n的所有素因子a1,a2,a3
  • 容斥:+m/a1+m/a2+m/a3-m/(a1*a2)-m/(a1*a3)-m/(a2*a3)+m/(a1*a2*a3)

【AC】

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 
 5 ll a,b,n;
 6 const int maxn=1e5+2;
 7 ll fac[maxn];
 8 int cnt;
 9 void factor(ll n)
10 {
11     cnt=0;
12     for(int i=2;i<maxn;i++)
13     {
14         if(n%i==0)
15         {
16             fac[cnt++]=i;
17         }
18         while(n%i==0)
19         {
20             n/=i;
21         }
22     }
23     if(n>1) fac[cnt++]=n;
24 }
25 ll solve(ll x)
26 {
27     ll que[maxn],k,t=0;
28     que[t++]=-1;
29     for(int i=0;i<cnt;i++)
30     {
31         k=t;
32         for(int j=0;j<k;j++)
33         {
34             que[t++]=que[j]*fac[i]*(-1);
35         }
36     }
37     ll ans=0;
38     for(int i=1;i<t;i++)
39     {
40         ans+=x/que[i];
41     }
42     return ans;
43 }
44 ll query(ll x)
45 {
46     return x-solve(x);
47 }
48 int main()
49 {
50     int T;
51     scanf("%d",&T);
52     int cas=0;
53     while(T--)
54     {
55         scanf("%I64d%I64d%I64d",&a,&b,&n);
56         factor(n);
57         ll ans=query(b)-query(a-1);
58         printf("Case #%d: %I64d
",++cas,ans);
59     }
60     return 0;
61 }
容斥
原文地址:https://www.cnblogs.com/itcsl/p/7429633.html