hdu4135Co-prime-容斥原理
来源:互联网 发布:知君的书法 编辑:程序博客网 时间:2024/06/10 12:15
题意:给定a、b、c,求a到b区间内与c互质的数。
分析:我们可以先转化下:用(1,b)区间与n互质的数的个数减去(1,a-1)区间与n互质的数的个数,那么现在就转化成求(1,m)区间于n
互质的数的个数,如果要求的是(1,n)区间与n互质的数的个数的话,我们直接求出n的欧拉函数值即可,可是这里是行不通的!我们不妨
换一种思路:就是求出(1,m)区间与n不互质的数的个数,假设为num,那么我们的答案就是:m-num!
举一组实例吧:假设m=12,n=30.
第一步:求出n的质因子:2,3,5;
第二步:(1,m)中是n的因子的倍数当然就不互质了(2,4,6,8,10)->n/2 6个,(3,6,9,12)->n/3 4个,(5,10)->n/5 2个。
如果是粗心的同学就把它们全部加起来就是:6+4+2=12个了,那你就大错特错了,里面明显出现了重复的,我们现在要处理的就是如何去掉那些重复的了!
第三步:这里就需要用到容斥原理了,公式就是:n/2+n/3+n/5-n/(2*3)-n/(2*5)-n/(3*5)+n/(2*3*5).
第四步:我们该如何实现呢?我在网上看到有几种实现方法:dfs(深搜),队列数组,位运算三种方法都可以!上述公式有一个特点:n除以奇数个数相乘的
时候是加,n除以偶数个数相乘的时候是减。我这里就写下用队列数组如何实现吧:我们可以把第一个元素设为-1然后具体看代码如何实现吧!
#include<cstdio>int j,a[1000];void init(int n){ int i; j=0; for(i=2;i*i<=n;i++) { if(n%i==0) { a[j++]=i; while(n%i==0) n/=i; } } if(n>1) a[j++]=n;}__int64 query(__int64 n){ __int64 b[10000],i,m,k,t=0,sum=0; b[t++]=-1; for(i=0;i<j;i++) { k=t; for(m=0;m<k;m++) { b[t++]=b[m]*a[i]*(-1); } } for(i=1;i<t;i++) sum+=n/b[i]; return sum;}int main(){ int n,i,t; __int64 x,y,m; scanf("%d",&t); for(i=1;i<=t;i++) { scanf("%I64d%I64d%d",&x,&y,&n); init(n); m=y-query(y)-(x-1-query(x-1)); printf("Case #%d: %I64d\n",i,m); }}
0 0
- hdu4135Co-prime-容斥原理
- hdu4135Co-prime 容斥原理水题
- hdu4135Co-prime
- hdu4135Co-prime
- [容斥原理] hdu 4135 Co-prime
- 【容斥原理】 HDOJ 4135 Co-prime
- 【HDU】4135 Co-prime 容斥原理
- hdu 4135 Co-prime(容斥原理)
- hdu 4135 Co-prime 容斥原理
- hdu 4135 Co-prime【容斥原理】
- hdu 4135 Co-prime (容斥原理)
- HDU4135 Co-prime【容斥原理】
- HDOJ 4135 Co-prime 容斥原理
- 【容斥原理】HDU 4135 Co-prime
- hdoj 4135 Co-prime 【容斥原理】
- hdu4135---Co-prime(容斥原理)
- HDU 4135 Co-prime (容斥原理)
- hdu4135 co-prime(容斥原理)
- 贪心
- 单例模式
- Flex 确认提示框
- Android卫星菜单的实现
- lce的回调实现(Bidirectional Connections)双向通信
- hdu4135Co-prime-容斥原理
- LoggerFactory.getLogger(String name)用法
- 【JAVA语言程序设计基础篇】--图形-- 绘制封装表格类的思考
- Git初体验(2)-暂存区和版本库
- linux创建和删除文件
- Redis集群
- redis集群测试
- python读取二进制文件中的浮点数数组
- 游标