I will no longer be |

yabnto

园龄:2年8个月粉丝:14关注:17

P3214 [HNOI2011] 卡农

形式化题意

1 n 个数,你可以从中选一些数形成一个组合(组合不能为空),然后将一些组合合在一起形成一个大组合,并要求大组合中的每个数都出现偶数次。

step 1

考虑偶数,我们想到异或操作,看到组合套组合,我们想到装压,两个一叠加,就成了第一步,将组合抽象化,变成一个状态,而偶数就是所有状态异或和为0

step 2

考虑到是组合套组合,那么状态便被锁的很死,所以尝试变成排列套组合,最后除序即可

step 3

排列套组合变成了我们熟悉的装压 dp,可是由于状态太大,且转移未知,所以需要一个新的状态以去除以上问题,考虑到目标状态是要为 0,所以将 dp 状态设为以当前组合结尾且状态异或和为 0 的方案数,那我们如何来却定当前状态与前面的异或和为 0 呢?我们可以设当前状态为前面的状态的异或和,那么考虑转移

step 4

其实既使这样转移也很复杂(这个要是不信,你自己正着做一遍吧),考虑用容斥,那么将分为一下两点:

1. 全部的方案数

考虑到由于当前的状态有前面的状态来得到,并且是唯一指定,所以只要考虑前面的编排,由于是排列套组合,所以是 A2n1m (这个没啥好说的)

2. 不合法的方案数

不合法的有两种:

  1. 在当前状态之前就已经结束了,那么当前状态肯定无法结束,因为组合一定要选,所以这里要减去的方案数为 fi1 即在 i1 就已经结束了的
  2. 很奇怪,为什么只要减去 fi1 的呢,因为这里还要剪掉一些,以上问题来看,如果在 i2(这个只是瞎列数) 的时候结束那么到 i 这里必然存在重复,所以这种不合法就处理重复(不要听我瞎逼逼,这里只是解释一下上面的,下面的才是重点),那么除了以上问题的角度,还有一个是如果出现重复,必然删掉两个数后任然是一个完整的状态(即可以用 f 表示的状态),所以这种不合法的方案首先有一个 fi2,那么会有多少种与前面的重复的可能?有 i1 种,最后有多少重复的数的可能呢?有 2n1 (i2) 为什么要减 i2 因为前面有 i2 个不与它相同,不然早就判掉了,只有删掉,才不会判重,那么这题就结束了。

step 5

真的结束了吗?其实一直遗留了一个问题,就是排列数怎么算,由于 2n1 的最终结果过大,不肯能用常规来做,但是我们可以用递推来解,考虑到排列数的式子是:

n!(nk)!

相当于是每 k+1 整个式子要乘上一个被分母释放出来的 nk+1,所以递推求解,这下真完了(除非你没听懂我的 dp 的状态设计,好像除序也没说,不过我觉得是个做题者(指做这道题的人),应该都会吧)

code

#include <iostream>
using namespace std;
using ll = long long;
const int MaxN = 2e6 + 10, mod = 1e8 + 7;
ll qpow(ll a, ll b) {
ll res = 1;
for (ll i = 1; i <= b; (b & i) && (res = res * a % mod), a = a * a % mod, i <<= 1) {
}
return res;
}
ll f[MaxN], ani[MaxN], n21, n, m, ma = 1;
int main() {
cin >> n >> m, f[f[0] = 1] = 0, n21 = ((qpow(2, n) - 1) % mod + mod) % mod, ani[ani[0] = 1] = n21;
for (int i = 2; i <= m; i++) {
ma = ma * i % mod;
ani[i] = ani[i - 1] * (((n21 - i + 1) % mod + mod) % mod) % mod;
f[i] = ((((ani[i - 1] - f[i - 1]) % mod + mod) % mod - (f[i - 2] * (i - 1) % mod * ((n21 - i + 2) % mod + mod) % mod) % mod) % mod + mod) % mod;
}
cout << f[m] * qpow(ma, mod - 2) % mod << endl;
return 0;
}

最短的代码,最无语的思路,这思路我打死都想不到

本文作者:yabnto

本文链接:https://www.cnblogs.com/ybtarr/p/18340206

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   yabnto  阅读(25)  评论(0编辑  收藏  举报
  1. 1 イエスタデイ(翻自 Official髭男dism) 茶泡饭,春茶,kobasolo
  2. 2 光辉岁月 Audio artist
  3. 3 名前を呼ぶよ Audio artist
  4. 4 战歌 Audio artist
  5. 5 時を越えた想い Audio artist
  6. 6 所念皆星河 Audio artist
  7. 7 See you again Audio artist
名前を呼ぶよ - Audio artist
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

Not available

点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起