poj 3904---容斥原理
hdu 1695---容斥原理
poj 1091---容斥原理
poj 2773---二分+容斥原理
poj 3904---容斥原理
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define N 10010
int 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]];
else
res+=h[p[i]];
}
}
cout<<res<<endl;
}
}
hdu 1695---容斥原理
#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 100010
int 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;
else
res+=b/tsum;
}
}
printf("Case %d: %I64d\n",he,res);
}
}
poj 1091---容斥原理
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define N 10010
int 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);
else
res+=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;
else
l=mid+1;
}
printf("%lld\n",r);
}
}