状态压缩与容斥原理

状态压缩的意思其实是挺简单的,就是以前在暴力解题时要开一个好大好大的数组,结果很不幸,最后发现没办法了,空间消耗太大,写法过于复杂。

然后如果使用了状态压缩之后就会发现,使用变得方便起来,而且真正消耗的空间相对于以前的数组基本上是可以忽略不计的。

但是这个还是有一定的缺陷的,因为二进制保存的长度有限,并不是说能够保存多大,大概的一个数量是20以内都没有问题,超过后就得考虑换一换方法了。这里将使用的方法的代码都保留下来。

#define LL long long

LL getans(LL num,int m)

//状态压缩,计算[1,num]中与n不互素的数的个数,m是n素因子的个数,在调用这个函数之前就是将结果全部计算出来了
{
LL ans=0,tmp,i,j,flag;

for(i=1; i<(LL)(1<<m); i++)//先乘以2^m这个数
{
tmp=1,flag=0;
for(j=0; j<m; j++)
if(i&((LL)(1<<j)))//这是一个进行位运算的过程
flag++,tmp*=prime[j];//flag是用来计算到底有几重计算的结果了,而tmp是用来反映
if(flag%2==1)//奇数加,偶数减
ans+=num/tmp;//计算与n有公共因子的数的个数
else
ans-=num/tmp;
}
return ans;
}

//在这里现将我在网上百度到的一段代码写出来,并讲讲自己的看法,最后在自己书写出自己的代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define LL long long
#define maxn 70

LL prime[maxn];//对于一些比较大的数组一般是开在main函数外面的,这样的使用才不会出问题
LL make_ans(LL num,int m)
{
LL ans=0,tmp,i,j,flag;
for(i=1;i<(LL)(1<<m);i++) //用二进制来1,0来表示第几个素因子是否被用到,如m=3,三个因子是2,3,5,则i=3时二进制是011,表示第2、3个因子被用到
{
tmp=1,flag=0;
for(j=0;j<m;j++)
if(i&((LL)(1<<j)))//判断第几个因子目前被用到
flag++,tmp*=prime[j];
if(flag&1)//容斥原理,奇加偶减
ans+=num/tmp;
else
ans-=num/tmp;
}
return ans;
}

int main()
{
int T,t=0,m;
LL n,a,b,i;

//对于这样的定义方式我不是特别的赞同,因为全部写在循环外面虽然是方便的变量的类型的定义,但是在使用时可能就不清楚它本身的含义了,可以借鉴
scanf("%d",&T);
while(T--)
{
scanf("%I64d%I64d%I64d",&a,&b,&n);//这里是将测试数据输入
m=0
for(i=2;i*i<=n;i++)

//对n进行素因子分解 ,学姐说开方后最多只会漏掉一个解的情况,那就是它本身,后面的if就是对这种情况的一个判断

if(n&&n%i==0)
{
prime[m++]=i;
while(n&&n%i==0)
n/=i;
} //这个分解过程其实也是非常简单的,主要是自己动手将整个过程写一写就会发现是将n的所有约数(除本身)保存在一个数组中
if(n>1)
prime[m++]=n;//后面的++是用来计数的,刚刚好弥补了数组从0开始使用的一个空缺
printf("Case #%d: %I64d\n",++t,(b-make_ans(b,m))-(a-1-make_ans(a-1,m)));

//最后是减法的原因非常简单,题目要求求解 的结果是互质,但是我们通过函数求解得到的是相反的结果,所以通过减法求得
}
return 0;
}

状态压缩与容斥原理

时间: 2024-10-11 03:03:52

状态压缩与容斥原理的相关文章

[poj3904]Sky Code_状态压缩_容斥原理

Sky Code poj-3904 题目大意:给你n个数,问能选出多少满足题意的组数. 注释:如果一个组数满足题意当且仅当这个组中有且只有4个数,且这4个数的最大公约数是1,$1\le n\le 10^4$. 想法:我们显然可以知道4个数是可以不用两两互质的,所以正面计算难度较大,我们考虑从反面考虑.我们通过计算所有gcd不为1的组数,用总组数相减即可.然后,我们发现一个不为0的gcd显然可以被组中的任意一个数整除,所以我们可以进行容斥.只需要枚举gcd的约数个即可.计算的过程我们用状态压缩实现

HDU 1796 How many integers can you find (状态压缩 + 容斥原理)

题目链接 题意 : 给你N,然后再给M个数,让你找小于N的并且能够整除M里的任意一个数的数有多少,0不算. 思路 :用了容斥原理 : ans = sum{ 整除一个的数 } - sum{ 整除两个的数 } + sum{ 整除三个的数 }………………所以是奇加偶减,而整除 k 个数的数可以表示成 lcm(A1,A2,…,Ak) 的倍数的形式.所以算出最小公倍数, //HDU 1796 #include <cstdio> #include <iostream> #include <

HDU 5768 Lucky7 (容斥原理 + 中国剩余定理 + 状态压缩 + 带膜乘法)

题意:……应该不用我说了,看起来就很容斥原理,很中国剩余定理…… 方法:因为题目中的n最大是15,使用状态压缩可以将所有的组合都举出来,然后再拆开成数组,进行中国剩余定理的运算,中国剩余定理能够求出同时满足余膜条件的最小整数x,x在(1,M)之间由唯一值,M是各个除数的乘积,所有符合条件的解为ans = x+k*M,可以知道在[1,R]这个区间内,有(M+R-x)/ M个k符合条件,然后在运算中为了防止溢出,所以使用了带膜乘法,就是将乘数转化为二进制,通过位移运算符,在中间过程中不断的取膜(看代

HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由于得到每张卡片的状态不知道,所以用状态压缩,dp[i] 表示这个状态时,要全部收齐卡片的期望. 由于有可能是什么也没有,所以我们要特殊判断一下.然后就和剩下的就简单了. 另一个方法就是状态压缩+容斥,同样每个状态表示收集的状态,由于每张卡都是独立,所以,每个卡片的期望就是1.0/p,然后要做的就是要去重,既然

Hdu 4336 Card Collector (状态概率DP|容斥原理)

详细的题目大意与解析大家参考一下kuangbin的文章. kuangbin链接 这边说一下自己对于kuangbin代码以及容斥原理位元素枚举的理解与解释,希望对大家有所帮助. 状态DP AC代码:状态压缩的思想我就不赘述了,我也只是略懂,这边仅仅分析一下状态方程 由于量比较多,我这边有的便用文字代替,有利于描述. dp[i]表示i状态达到满状态(即收集满n个物品,以下称满状态)所需要的期望. 那么i状态当中收集了x的物品,剩余n-x个物品没有收集 那么dp[i]=p*dp[i]+p2*dp[i2

胜利大逃亡(续)(状态压缩bfs)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7357    Accepted Submission(s): 2552 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

uva 818(dfs+图+状态压缩)

题意:有n个环,编号从1到n,给出了一些环环相扣的情况,比如给a和b表示a和b两个环的扣在一起的,每个环都是可以打开的,问最少打开多少个环,然后再扣好,可以让所有的环成为一条链. 题解:状态压缩把所有的打开环的情况枚举出来,然后拿去判断是否成立,更新打开环后的图g[i][j],和每个点的度数,不成立有三种情况,1.计算没有打开的环的度数,如果大于2说明不会有链,2.把没有打开环拿去dfs,访问过就vis[i]++,如果vis[i]>=2说明存在环,3.如果打开的环数num + 1小于链的数量,说

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

uva 11195 Another queen (用状态压缩解决N后问题)

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2136 Problem A Another n-Queen Problem I guess the n-queen problem is known by every person who has studied backtracking. In this problem you s