hdu 1695 hdu 4135 容斥原理求1-n 区间内与r互质的个数
方法:
先对n分解质因数,分别记录每个质因数,那么所求区间内与某个质因数不互质的个数就是n / r(i),假设r(i)是r的某个质因子。
假设只有三个质因子,总的不互质的个数应该为p1+p2+p3-p1*p2-p1*p3-p2*p3+p1*p2*p3,及容斥原理,可以转向百度百科查看相关内容
pi代表n/r(i),即与某个质因子不互质的数的个数
当有更多个质因子的时候,可以用状态压缩解决,二进制位上是1表示这个质因子被取进去了。如果有奇数个1,就相加,反之则相减
View Code
#include<vector>
#include<cstdio>
using namespace std;
__int64 solve(int r,__int64 n){
vector<int> p;
int i;
for(i=2;i*i<=r;i++){
if(r%i==0){
p.push_back(i);
while(r%i==0){
r/=i;
}
}
}
if(r>1) p.push_back(r);
__int64 sum=0;
for(int num=1;num<(1<<p.size());num++){
__int64 mult=1,ones=0;
for(i=0;i<p.size();i++){
if(num&(1<<i)){
ones++;
mult*=p[i];
}
}
if(ones%2) sum+=n/mult;
else sum-=n/mult;
}
return n-sum;
}
int main(){
int t,c;
__int64 a,b;
__int64 cases=1;
scanf("%d",&t);
while(t--){
scanf("%I64d%I64d%d",&a,&b,&c);
printf("Case #%I64d: %I64d\n",cases++,solve(c,b)-solve(c,a-1));
}
return 0;
}
hdu 1695
View Code
#include<vector> #include<cstdio> using namespace std; int prm[50000]; int tot=0; bool flag[100010]; void init() { int i,j; memset(flag,false,sizeof(flag)); for(i=2;i<=100000;i++) { for(j=2*i;j<=100000;j+=i) { flag[j]=true; } } for(i=2;i<=100000;i++) { if(!flag[i]) prm[++tot]=i; } } __int64 solve(int r,__int64 n){ int p[50]; int cnt=0; int i; if(!flag[r]) { if(r>1) p[cnt++]=r; } else { for(i=1;i<=tot;i++) { if(r%prm[i]==0) { p[cnt++]=prm[i]; while(r%prm[i]==0) r/=prm[i]; if(!flag[r]) { if(r>1) { p[cnt++]=r;r=1; } break; } } }if(r>1) p[cnt++]=r; } __int64 sum=0; for(int num=1;num<(1<<cnt);num++){ __int64 mult=1,ones=0; for(i=0;i<cnt;i++){ if(num&(1<<i)){ ones++; mult*=p[i]; } } if(ones%2) sum+=n/mult; else sum-=n/mult; } return n-sum; } int main(){ int t; init(); __int64 a,b,c,d,e; __int64 cases=1; scanf("%d",&t); while(t--){ scanf("%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&d,&e); if(e==0||b<e||d<e) { printf("Case %I64d: 0\n",cases++); continue; } a = b < d ? b : d; b = b > d ? b : d; a /= e; b /= e; __int64 ans=0; for(int i=1;i<=a;i++) { if(i>1) ans+=solve(i,b)-solve(i,i-1); else ans+=b; } printf("Case %I64d: %I64d\n",cases++,ans); } return 0; }