容斥原理+质因数分解+组合数学

来源:互联网 发布:状态机编程 编辑:程序博客网 时间:2024/05/02 04:30


poj 3904---容斥原理

hdu 1695---容斥原理

poj 1091---容斥原理

poj 2773---二分+容斥原理


poj 3904---容斥原理

http://blog.csdn.net/duanxian0621/article/details/7313707

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define ll long long#define N 10010int p[N],g[N];int t[20];ll h[N];void solve(int x){int i,j,k,cnt=0;for(i=2;i*i<=x;i++){if(x%i==0){t[cnt++]=i;while(x%i==0)x/=i;}}if(x!=1)t[cnt++]=x;int tt=(1<<cnt);for(i=1;i<tt;i++){int tsum=1,tflag=0;for(j=0;j<cnt;j++){if((i>>j)&1){tsum*=t[j];tflag++;}}p[tsum]++;g[tsum]=tflag;}}int main(){int n;ll i,j,k;h[0]=h[1]=h[2]=h[3]=0;for(i=4;i<=10000;i++){h[i]=i*(i-1)*(i-2)*(i-3)/24;}while(scanf("%d",&n)!=EOF){memset(p,0,sizeof(p));memset(g,0,sizeof(g));for(i=0;i<n;i++){scanf("%d",&k);solve(k);}ll res=h[n];for(i=1;i<=10000;i++){if(p[i]!=0){if(g[i]&1)res-=h[p[i]];elseres+=h[p[i]];}}cout<<res<<endl;}}

hdu 1695---容斥原理

http://www.cnblogs.com/jiaohuang/archive/2011/01/15/1936509.html

#include<cstdio>  #include<cstring>  #include<string.h>#include<stdio.h>#include<algorithm>  #include<iostream>  #include<cstdlib>  #include<vector>  #include<set>#include<cmath>  #include<math.h>using namespace std;  #define inf 0x3f3f3f3f  #define ll __int64#define N 100010int prime[N+10];  ll phi[N+10];  ll sum[N+10]; void dabiao()  {      int i,j,k;      memset(prime,0,sizeof(prime));      for(i=2;i*i<N;i++)          if(!prime[i])              for(j=i*i;j<N;j+=i)                  prime[j]=1;      for(i=1;i<N;i++)          phi[i]=i;      for(i=2;i<N;i++)          if(!prime[i])              for(j=i;j<N;j+=i)                  phi[j]=phi[j]/i*(i-1);      sum[1]=1;      //sum[2]=phi[2];      for(i=2;i<N;i++)          sum[i]=sum[i-1]+phi[i];  }  int h[30];int main(){int i,j,k,t;scanf("%d",&t);int he=0;dabiao();while(t--){he++;int a,c,b,d;scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);if(k==0){printf("Case %d: 0\n",he);continue;}if(b>d) swap(b,d);b/=k,d/=k;ll res=sum[b];for(i=b+1;i<=d;i++){res+=b;int cnt=0;int te=i;for(j=2;j*j<=te;j++){if(te%j==0){h[cnt++]=j;while(te%j==0)te/=j;}}if(te!=1)h[cnt++]=te;int tt=(1<<cnt);for(j=1;j<tt;j++){int tsum=1,tflag=0;for(k=0;k<cnt;k++){if((j>>k)&1){tsum*=h[k];tflag++;}}if(tflag&1)res-=b/tsum;elseres+=b/tsum;}}printf("Case %d: %I64d\n",he,res);}}

poj 1091---容斥原理

http://blog.csdn.net/bobten2008/article/details/4473864

#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define ll long long#define N 10010int t[20];int n;ll m;ll qpow(ll x){ll sum=1;for(int i=0;i<n;i++)sum*=x;return sum;}void solve(ll x){int i,j,k,cnt=0;for(i=2;i*i<=x;i++){if(x%i==0){t[cnt++]=i;while(x%i==0)x/=i;}}if(x!=1)t[cnt++]=x;int tt=(1<<cnt);ll res=qpow(m);for(i=1;i<tt;i++){int tsum=1,tflag=0;for(j=0;j<cnt;j++){if((i>>j)&1){tsum*=t[j];tflag++;}}if(tflag&1)res-=qpow(m/tsum);elseres+=qpow(m/tsum);}cout<<res<<endl;}int main(){int i,j,k;scanf("%d%lld",&n,&m);solve(m);//system("pause");}


poj 2773---二分+容斥原理

<pre name="code" class="cpp">#include<iostream>  #include<stdio.h>  #include<string.h>  #include<algorithm>  using namespace std;  #define ll long long  #define inf 0x3f3f3f3f  #define N 10010    ll gcd(ll a,ll b)  {      return b?gcd(b,a%b):a;  }  ll h[20];  ll p[20000];  ll f[20000];  ll tcnt;    ll solve(ll x)  {      ll res=x;      for(ll i=0;i<tcnt;i++)      {          if(f[i]&1)              res-=x/p[i];          else              res+=x/p[i];      }      return res;  }  int main()  {      ll i,j,k,m;      while(scanf("%lld%lld",&m,&k)!=EOF)      {          ll l=0,r=1000000000000,mid,ans,flag;          ll cnt=0,t=m;          for(i=2;i*i<=t;i++)          {              if(t%i==0)              {                  h[cnt++]=i;                  while(t%i==0)                      t/=i;              }          }          if(t!=1)              h[cnt++]=t;          ll tt=(1<<cnt);          tcnt=0;          for(i=1;i<tt;i++)          {              ll tsum=1,tflag=0;              for(j=0;j<cnt;j++)              {                  if((i>>j)&1)                  {                      tsum*=h[j];                      tflag++;                  }              }              p[tcnt]=tsum;              f[tcnt++]=tflag;          }          while(l<r)          {              mid=(l+r)/2;              ans=solve(mid);              if(ans>=k)r=mid;elsel=mid+1;        }          printf("%lld\n",r);      }  }  


                                             
0 0