关于数的容斥定理的代码实现
来源:互联网 发布:软件配置管理招聘 编辑:程序博客网 时间:2024/04/28 18:15
前述:其实容斥定理的用法并非自己感悟出来的,还是从大量博客里学习的,感觉这种深邃的思想我学不来,看题目的时候都想不到为什么要那样用,但是容斥定理本身是很简单的,公式我就不再展示了。但是还好因为集合的交集的求法比较困难,使得这方面能用固定代码解决的问题的种类大大减少。其中比较广泛的一个应用就是求1-m里面和n互质的数的个数。思路是用m-所有和n非互质的数的和,那么,和n非互质又有一个说法就是和n有大于1的公共素因子,而属于有某个因子a的数的个数的集合个数就是m/a。这样,问题就转化成了这样几个步骤:1.先求n的所有素因子。2.根据容斥定理求和n非互质的数的个数。3.ans=m-和n非互质的数的个数。那么这里我为啥说是代码实现而不说是模板呢,在dalao的博客里面我发现的写法要么是难懂的位运算,要么不用递归难想,而我选择了最直接也可能是最耗时间的解决方法,就是dfs递归,一开始只是出于试探的心理,后来交了几个题目之后发现并未出现超时的现象,于是就当作一个模板来用了,也做出来不少容斥定理的题目。
AC代码:(参见题目:HDU-4135 J - Co-prime )
题目大意:让求一个区间里面和n互质的数的个数。
解题思路:假设为[l,r],那么有可以用1-r满足条件的数的个数1-l-1中满足条件的数的个数。
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
long long fac[1100];
long long box[1100];
long long n,m,t;
long long fun;
long long gcd(long long a,long long b){
return b==0?a:gcd(b,a%b);
}
void getfac(){
long long i,j;
long long xx=n;
m=0;
for (i=2;i<=sqrt(n);i++){
if (xx%i==0){
fac[++m]=i;
while (xx%i==0){
xx/=i;
}
}
}
if (xx>1)fac[++m]=xx;
}
void sfind(long long x,long long y,long long z,long long val){
long long i,j;
for (i=x;i<=m;i++){
box[y]=fac[i];
if (y==z){
long long temp=1;
for (j=1;j<=z;j++){
temp=temp/gcd(temp,box[j])*box[j];
}
fun+=val/temp;
}
else sfind(i+1,y+1,z,val);
}
}
long long solve(long long x){
long long i,j;
long long temp=1;
long long ans=0;
for (i=1;i<=m;i++){
fun=0;
sfind(1,1,i,x);
ans+=fun*temp;
temp=-temp;
}
return x-ans;
}
int main(){
long long i,j,k,l,r,total,cas=0;
scanf("%lld",&t);
while (t--){
scanf("%lld%lld%lld",&l,&r,&n);
getfac();
long long ans=solve(r)-solve(l-1);
printf("Case #%lld: %lld\n",++cas,ans);
}
}
这个题目其实不是我创造出来这个写法的初始版本,这里改造成了一个函数,可以更为广泛的应用。
- 关于数的容斥定理的代码实现
- 关于错排的容斥定理的一些心得
- Tmutarakan Exams 简单的容斥定理
- 容斥定理的简单应用
- 1248: HH的军训[容斥定理]
- HDU 4135(基本的容斥定理)
- 杭电2841 容斥定理求1到n之间和x互质的数的总数
- 互斥的数
- 互斥的数
- 互斥的数
- 携程——聪明的猴子 (容斥定理)
- GCD SUM 强大的数论,容斥定理
- nyoj-471 好多的树[容斥定理]
- HDU_2841_Visible Trees && NYOJ_471_好多的树 容斥定理
- 容斥定理 1284 2 3 5 7的倍数
- Visible Trees HDU2841(容斥定理的简单扩展)
- 组合计数(容斥定理+卢卡斯定理的正确姿势)
- 数论 + 容斥定理
- e-charts属性详解
- PAT
- NodeMCU--学习笔记(二)连接wifi
- 一到x之间的阶乘
- 380. Insert Delete GetRandom O(1)
- 关于数的容斥定理的代码实现
- 解决ubuntu16.04只能用客人会话登陆的问题
- 62. Unique Paths
- html5项目总结
- 深度学习实践操作—从小白到大白(八):安装Pytorch到特定的Anaconda环境
- Android 自定义view 圆形进度条1
- 63. Unique Paths II
- $.ajax 和$.post的区别
- 自定义控件(二) 从源码分析事件分发机制