容斥原理

Posted pangbi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了容斥原理相关的知识,希望对你有一定的参考价值。

题目链接:https://nanti.jisuanke.com/t/A1995

题意:给出递推式,我们可以算出a【n】=n*n+n;

那么Sn=n*(n+1)(2*n+1)/6+n*(n+1)/2;

我们有这样一个容斥定理:区间中与i不互质的个数=(区间中i的每个质因素的倍数个数)-(区间中i的每两个质因素的乘积的倍数个数)+

(区间中i的3个)-(4....)+(5....)-(6....)+(7.....)......  (偶数减,奇数加)

所以我们可以通过算出前n项和,再减去不互质的项的和,即为答案,

但是不互质的个数可能很多,一一枚举会导致超时,所以我们可以利用性质一次枚举多个;

假如我们枚举到某质因素乘积为k,那么根据原式可得技术图片,求得Sn为:技术图片

 

于是这道题就解决了

  1 #include<queue>
  2 #include<cstring>
  3 #include<string>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<cstdio>
  7 #include<set>
  8 using namespace std;
  9 typedef long long ll;
 10 const int maxn=100000;
 11 const int mod=1e9+7;
 12 ll mo(ll a,ll pp){
 13     if(a>=0&&a<pp)return a;
 14     a%=pp;
 15     if(a<0)a+=pp;
 16     return a;
 17 }
 18 ll powmod(ll a,ll b,ll pp){
 19     ll ans=1;
 20     for(;b;b>>=1,a=mo(a*a,pp)){
 21         if(b&1)ans=mo(ans*a,pp);
 22     }
 23     return ans;
 24 }
 25  
 26 ll inv1(ll b){
 27     return powmod(b,mod-2,mod);
 28 }
 29 bool check[maxn+7];
 30 int phi[maxn+7];
 31 int prime[maxn+7];
 32 int tot;
 33 void phi_and_prime_table(int N) {
 34     memset(check,false,sizeof(check));
 35     phi[1]=1;
 36     tot=0;
 37     for(int i=2; i<=N; i++) {
 38         if(!check[i]) {
 39             prime[tot++]=i;
 40             phi[i]=i-1;
 41         }
 42         for(int j=0; j<tot; j++) {
 43             if(i*prime[j]>N)break;
 44             check[i*prime[j]]=true;
 45             if(i%prime[j]==0) {
 46                 phi[i*prime[j]]=phi[i]*prime[j];
 47                 break;
 48             }
 49             else{
 50                 phi[i*prime[j]]=phi[i]*(prime[j]-1);
 51             }
 52         }
 53     }
 54 }
 55 int p[107],dex[107];
 56 int getFactors(ll x) {//分解质因数 
 57     int fatcnt=0;
 58     ll tmp=x;
 59     for(int i=0; prime[i]<=tmp/prime[i]; i++) {
 60         dex[fatcnt]=0;
 61         if(tmp%prime[i]==0) {
 62             p[fatcnt]=prime[i];
 63             while(tmp%prime[i]==0) {
 64                 dex[fatcnt]++;
 65                 tmp/=prime[i];
 66             }
 67             fatcnt++;
 68         }
 69     }
 70     if(tmp!=1) {
 71         p[fatcnt]=tmp;
 72         dex[fatcnt++]=1;
 73     }
 74     return fatcnt;
 75 }
 76 ll N;
 77 ll S(ll x){
 78     ll n=N/x;
 79     ll sum=(n*(n+1)%mod*(2*n+1)%mod)*inv1(6)%mod*x%mod*x%mod+n*(n+1)%mod*inv1(2)%mod*x%mod;
 80     sum%=mod;
 81     return sum;
 82 }
 83 int main() {
 84     phi_and_prime_table(maxn);
 85     ll m;
 86     while(~scanf("%lld%lld",&N,&m)){
 87         int num=getFactors(m);//素因子个数 
 88         ll sum=S(1);
 89         ll s=0;
 90         for(int state=1;state<(1<<num);state++){//遍历所有状态 
 91             int tmp=1;
 92             int cnt=0;
 93             for(int i=0;i<num;i++){
 94                 if(state&(1<<i)){
 95                     cnt++;
 96                     tmp*=p[i];
 97                 }
 98             }
 99             if(cnt&1){//容斥 
100                 s=(s+S(tmp))%mod;
101             }
102             else{
103                 s=(s-S(tmp)+mod)%mod;
104             }
105         
106         }
107         sum=(sum+mod-s)%mod;
108         printf("%lld
",sum);
109     }
110     return 0;
111 }
112 ————————————————
113 版权声明:本文为CSDN博主「别动我的白羊毛」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
114 原文链接:https://blog.csdn.net/yz467796454/article/details/82531727

 

以上是关于容斥原理的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1853幸运数字——容斥原理

POJ 2773 容斥原理

hdu4153(容斥原理求质数)

bzoj 2393 Cirno的完美算数教室(容斥原理+搜索)

Codeforces1036F Relatively Prime Powers 容斥原理

POJ 2155 Matrix(树状数组+容斥原理)