您的位置:首页 > 其它

hdu 1695 hdu 4135 容斥原理求1-n 区间内与r互质的个数

2012-01-03 12:31 441 查看
方法:

先对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;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: