牛客多校05K题 Perfect Journey

这把牛客多校的A和K都不会(第四和第五题),但是发现B和C都很简单(虽然过的人比较少),过了5题。发现自己对FWT等多项式算法的理解还不是很够,写一个博客记录一下。

题意

一个 n ( n ≤ 2 ∗ 1 0 5 ) n(n\le 2*10^5) n(n2105) 个结点的树上面有 m ( m ≤ 22 ) m(m\le 22) m(m22) 特别的边。给定 k ( k ≤ 2 ∗ 1 0 5 ) k(k\le 2*10^5) k(k2105) 条路径,问你从这 k k k 条路径中最少选出多少条能够覆盖调所有的特别边,并求出方案数。

思路

转换成二进制,然后题意等价于从 k k k 个整数里面选择最少的数使得全部或起来是 2 m − 1 2^m-1 2m1

然后可以写成 min ⁡ t [ x 2 m − 1 ] ( ∑ i = 0 2 m − 1 a i x i ) t > 0 \min\limits_{t}[x^{2^m-1}](\sum\limits_{i=0}^{2^m-1}a_ix^i)^t>0 tmin[x2m1](i=02m1aixi)t>0

定义 x i × x j = x i ∣ j x^i\times x^j=x^{i|j} xi×xj=xij a i a_i ai 为路径中覆盖集合为 i i i 的个数。

然后只需要先对 ∑ i = 0 2 m − 1 a i x i \sum\limits_{i=0}^{2^m-1}a_ix^i i=02m1aixi 进行一次 FWT,然后判断最少乘几次以后最高次项为 > 0 >0 >0,让后对其系数乘上 1 t ! \frac{1}{t!} t!1 即可

这样的复杂度是 O ( m 2 2 m ) O(m^22^m) O(m22m) 的,会超时

考虑使用二分,可以优化到 O ( m 2 m log ⁡ m ) O(m2^m\log m) O(m2mlogm) 貌似已经可以通过。

因为我们只需要求出最高次项的系数,因此可以研究一下 iFWT 的过程。

void iOR(int *f) {
    for (int o = 2, k = 1; o <= lim; o <<= 1, k <<= 1) {
        for (int i = 0; i < lim; i += o) {
            for (int j = 0; j < k; j++) {
                f[i + j + k] = (f[i + j + k] - f[i + j] + mod) % mod;
            }
        }
    }
}

每一项对最高次项的系数的贡献都是 − 1 -1 1 或者 1 1 1,如果其二进制有一个 0 0 0,就会反转一次。

因此总的贡献就是 ∑ i = 0 2 m − 1 ( − 1 ) p o p c n t ( i ⊕ m a s k ) f i \sum\limits_{i=0}^{2^m-1}(-1)^{popcnt(i\oplus mask)}f_i i=02m1(1)popcnt(imask)fi,其中 m a s k = 2 m − 1 mask=2^m-1 mask=2m1

code

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值