容斥原理小结

数学修养过低,努力学习

POJ 3370

题意:给你一些数,让你取其中几个,模c得0,输出取的数的序号,不行的话输出no

题解:这题就是典型的鸽巢原理,构造序列a1,a1+a2,a1+a2+a3,........a1+a2+...+an

这样n个数的序列,然后都模c,看有没有相等的两个数,因为如果sumi==sumj,那么ai+1+ai+2+......+aj就能模c得0,如果有sumj=0modc,那么 从a1到aj也是满足的

如果找不到那就没有。

因为n>=c,这样一个长度为n的序列模c之后的余数,如果有相同,那么存在,如果每个余数都不同,n==c,余数为0,1,2........c-1,那么余数为0的就行了

这题很容易T,不造为啥,但是方法就是这样的

AC代码:http://paste.ubuntu.net/13470920/

POJ 2356 

和上一题差不多,这题输出的是选中的数是多少

不贴了


HDU 1796

题意:给你一个n,然后给你个集合,问你小于n的数里面,能被这个集合里任何一个整除的数有多少个

题解:容斥原理,用二进制枚举,加上能被一个整除的,减去两个整除的(这里要取lcm),就这样,基础题

AC代码:http://paste.ubuntu.net/13471022/


HDU 3929

题意:给你一个多项式F(x) = (1+x)^a1 + (1+x)^a2 + ... + (1+x)^am

然后问你所有项中,系数为奇数的个数

这题还是挺难的,从二项式定理来考虑,好像并不好做,而且也不可能枚举啊

Lucas定理有这样一个推广,在判断组合数奇偶的时候,Lucas定理是这么说的

C(a[0],b[0])C(a[1],b[1])......C(a[n],b[n]);

每一位a[i]和b[i]都是0或者1,C(1,0)=1,C(0,0)=1,C(1,1)=1,C(0,1)=0;

所以如果想要这个组合数为奇数,ai用二进制表示,在ai为1的位置,k可以为0或者1,ai为0的位置,k必为0,这样组合数必为奇数

然后就来考虑a1,a2,a3........am

首先二进制枚举,只有一个数字的时候,他的1的个数tot,(1<<tot)就是系数为奇数的,

有两个数字的时候,他们俩与一下,得到的这个二进制数,(1<<tot)的个数是系数为偶数的,必须减去,然而这个位置在前两个数单个算的时候加了两次,所以这次要减去2倍的,然后在考虑有三个数的时候,三个数与得到的这个数字的(1<<tot)肯定是奇数,所以要加上,但是前面3个单个的加了一共3次,3个两个的减去了一共6次,这会需要加上这个3个数的位置,所以必须加4次。

这样就找到了这个解法的规律,就是按照每次枚举的二进制数里面有几个1,就是乘几次(-2)。

然而还有个问题就是这题数据组数比较多,用二进制枚举会TLE, 但是这题只要考虑二进制的与运算,所以用dfs写会快不少

还有个坑点就是计算x二进制表示中有多少个1,ai都是2^45,所以用库里面的那个popcount貌似不行,那个只能算32位,所以必须手写个

AC代码:http://paste.ubuntu.net/13471032/


HDU 4451

题意:给你衣服裤子鞋子的搭配,然后有些不能出现,问你能有多少种可以出现的搭配

题解:这题比较水,就是算出总数,然后记录哪些搭配是不能出现的,但是不太好写,所以用了链式前向星当成图来保存关系

因为如果衣服1和裤子1不能搭配,那么就有k种搭配不能出现,如果裤子1和鞋子1不能搭配,那么就有n种不能出现,但是这里面减去了两次1,1,1

所以需要建图来加上

AC代码:http://paste.ubuntu.net/13471286/


HDU 4336

题意:这题是给你一些牌,每个牌抽到的概率是多少,然后问你收集满所有卡的期望

题解:收集一张卡就是1/pi,但是这里面也有可能开出来别的卡,所以需要减去1/pipj,三个的就加上

其实概率这个我不怎么理解,就是瞎搞,寒假必须好好学学概率论了

AC代码:http://paste.ubuntu.net/13471311/



HDU 4407

题意:有两种操作,一种是把某个数改成c,一种是问区间里和p互素的有多少个,原本n个数是1,2,3,4....n

题解:修改用一个数组记录,因为只有1000次操作,所以直接暴力枚举每次修改改了什么就行,然后在询问的时候,在区间里用容斥原理搞出所以互素的数,然后枚举修改的位置,如果在区间里,就考虑此时是否互素,原来是否互素,加加减减就行

AC代码:http://paste.ubuntu.net/13471352/


POJ 1091

题意:最后题是给你一个m,然后找n张小于等于m的卡,然后怎么跳能跳到边上一格,问有多少种卡片的组合

题解:这就是扩展欧几里德的变形 a1x1+a2x2+a3x3+。。。+anxn=1

右边是1,左边的数的gcd必须是右边的因子,所以左边的系数的gcd必须是1

这题不能统计出因子的倍数的总数,因为2,3都是因子,但是2,3也是gcd==1所以不能这么算

所以可以把m分解,n张卡先是有m个选择,然后考虑单个因子,是这个因子的倍数的卡有a个,要减去a^n,然后考虑两个因子的,因为选择这些卡的情况在单个里面重复考虑了,所以加上就好了

这题要用高精度

AC代码:http://paste.ubuntu.net/13471528/


改天要好好学习莫比乌斯了








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值