count_prime----容斥+唯一分解定理
2016-05-09 19:00
260 查看
题目链接:http://icpc.njust.edu.cn/Contest/749/C/
此题是容斥+唯一分解定理,建议先去学习前置技能,这两个知识点都很好理解,适当的去学一下唯一分解定理的扩展应用(虽说到现在我还没有做到关于他应用的题=-=)。
求一个区间中有多少个数和给定的数字互斥(互质),需要对给定的数字进行素因数分解,然后利用二进制0 1的特性去组合每一个数字,最后利用容斥的奇加偶减原理去计数
附上南阳理工大学给出的官方题解:
容斥原理、先对n分解质因数,分别记录每个质因数,那么所求区间内与某个质因数不互质的个数就是n/r(i),假设r(i)是r的某个质因子 假设只有三个质因子,总的不互质的个数应该为p1+p2+p3-p1p2-p1p3-p2p3+p1p2*p3,
及容斥原理,pi代表n/r(i),即与某个质因子不互质的数的个数,当有更多个质因子的时候,可以用状态压缩解决,二进制位上是1表示这个质因子被取进去了。如果有奇数个1就相加,反之则相减。
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <cstring> using namespace std; long long prime[70]; long long m,n; void get_prime() { for(ll i=2;i*i<=n;i++) if(n&&n%i==0) //对n进行素因数分解 { prime[m++]=i; while(n&&n%i==0) n/=i; } if(n>1) prime[m++]=n; } long long solve(ll num) { ll i,j; ll ans=0,tem,flag; for(i=1;i<1<<m;i++) { tem=1,flag=0; for(j=0;j<m;j++) if(i&1<<j) flag++,tem*=prime[j]; if(flag&1) ans+=num/tem; //容斥原理,奇加偶减 else ans-=num/tem; } return ans; } int main() { long long t,a,b; cin>>t; while(t--) { m=0; scanf("%lld%lld%lld",&a,&b,&n); get_prime(); printf("%lld\n",b-solve(b)-(a-1-solve(a-1))); } return 0; }
相关文章推荐
- 大数据工程师技能图谱(转)
- 单例设计模式续--有上限的多例设计
- [Learn Android Studio 汉化教程]第一章 : Android Studio 介绍
- android studio 1.3.2创建的Hello World工程在老版本系统的手机上运行错误
- 关于hadoop2.x(2.7.1 2.7.2)集群配置和测试运行中Ubuntu虚拟机VM设置nat方式导致节点传输问题
- 栈和堆的区别
- GridFS图片
- Android - 通过真实案例学习解内存泄漏问题,最终发现Android原生Bug
- fastjson源码
- poj-1979 dfs
- C++ Primer 学习笔记_84_模板与泛型编程 -模板特化
- Eclipse设置:背景与字体大小和xml文件中字体大小调整
- Html+CSS_居中布局的总结
- C++ Primer 学习笔记_83_模板与泛型编程 -一个泛型句柄类
- 第三章:IPython交互式开发环境Day5
- 单元测试
- C++ Primer 学习笔记_82_模板与泛型编程 -类模板成员[续二]
- PC使用
- 数据结构--用栈求解迷宫问题(非最优解)
- 通过反射获取私有构造方法并使用