您的位置:首页 > 其它

hdu4135 容斥原理

2014-07-23 18:00 211 查看
题意:

给出A,B,N,求出[A,B]范围内与N互素的数字的个数。

即B范围内的不与N互素的数减去A范围内不与N互素的数,把[1,A],[1,B]中不与N互素的数分别求出来,再减掉就是和N互素的数了。

那么首先将N分解质因数,因子和因子的倍数可以被除尽,一定不与N互素,把这些数都记下来,筛法求素数即可~

然后把这些数和倍数加起来?果断会有重复,所以这就到容斥原理了,其实这个画个韦恩图就好~

奇数加偶数减,用队列,位运算,dfs都可以实现,不过那个位运算的搞了好久现在暂时还是没懂。。

下面的代码是队列。

#include<stdio.h>
#include<string.h>
using namespace std;
long long a[1000],num;
void prime(long long n)
{
long long i;
num=0;
for(i=2;i*i<=n;i++)
{
if(n%i==0)
{
a[num++]=i;
while(n%i==0)
n=n/i;
}
}
if(n>1)
a[num++]=n;
}
long long get(long long m)
{
long long que[10000],k,t=0,sum=0;
que[t++]=-1;
for(int i=0;i<num;i++)
{
k=t;
for(int j=0;j<k;j++)
que[t++]=que[j]*a[i]*(-1);
}
for(int i=1;i<t;i++)
sum=sum+m/que[i];
return sum;
}

int main()
{
long long T,x,y,n,cnt;
while(scanf("%lld",&T)!=EOF)
{
for(int i=1;i<=T;i++)
{
scanf("%lld%lld%lld",&x,&y,&n);
prime(n);
cnt=y-get(y)-(x-1-get(x-1));
printf("Case #%d: ",i);
printf("%lld\n",cnt);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: