CF1614 - Codeforces Round 757 (Div. 2)

比赛链接

C. Divan and bitwise operations

题意

存在一个长度为 nn 的正整数序列 {ai}\{a_i\}mm 个限制条件,每个限制条件由 l,r,xl, r, x 构成,表示 {ai}\{a_i\} 在区间 [l,r][l,r] 中的元素或运算值为 xx。对于任意一个满足该条件的序列,求该序列的所有子序列异或值之和,结果对 109+710^9+7 取模。

数据范围:1n,m21051\leqslant n, m\leqslant 2\cdot10^5

思路

开始自己从每一位 aia_i 的取值去想的,结果发现根本无法求出所有子序列的异或值之和,看了题解才发现这题巨妙(

既然不容易求出每个子序列然后进行异或再求和,那就直接考虑异或运算下的子序列对答案的贡献。

考虑二进制位的第 ii 位,如果所有的 xx 或起来这一位都是 00,那么就不存在 aja_j 的第 ii11

现在考虑存在第 ii 位为 11aja_j,令集合 AA 为所有 aja_jii 位为 00BB 为所有 aja_jii 位为 11,则 A+B=n|A|+|B| = n

直接从子序列角度分析,一个子序列可以视为分别从集合 AA 和集合 BB 中取出元素,按照原有顺序,构成子序列,所以一个子序列的第 ii 位异或值为 11,当且仅当,它选取了奇数个 BB 中的元素,也就是

=(B1)+(B3)++(Bk)\sum = \binom{|B|}{1}+\binom{|B|}{3}+\cdots+\binom{|B|}{k}

如果 B|B| 为奇数,则 k=Bk=|B|,否则 k=B1k=|B|-1。利用二项式系数的递推式,可以得到

=(B10)+(B11)+(B12)+(B13)++(B1B1)=2B1\sum = \binom{|B|-1}{0}+\binom{|B|-1}{1}+\binom{|B|-1}{2}+\binom{|B|-1}{3}+\cdots+\binom{|B|-1}{|B|-1} = 2^{|B|-1}

于是第 ii 位为 11 的子序列个数为

2A=2A2B1=2A+B1=2n12^{|A|} \cdot \sum = 2^{|A|}\cdot 2^{|B|-1}=2^{|A|+|B|-1}=2^{n-1}

故,无论 A,BA,B 中元素如何,只要 BB\neq \varnothing,第 ii 位为 11 的子序列的个数都为定值 2n12^{n-1}

BB\neq \varnothing 等价于所有 xx 或起来第 ii 位为 11,那么对所有子序列求和,答案就是

2n1ORi=1mxi2^{n-1}\cdot\mathop{\text{OR}}\limits_{i=1}^mx_i

D1. Divan and Kostomuksha (easy version)

题意

给出一个序列 {ai}\{a_i\},可以对该序列进行重排,求重排后

Sn=i=1ngcd(a1,a2,,ai)=:i=1ng(i)S_n = \sum_{i=1}^n\text{gcd}(a_1,a_2,\cdots,a_i) =: \sum_{i=1}^n g(i)

的最大值。

数据范围:1n105,1ai51061\leqslant n\leqslant 10^5, 1\leqslant a_i\leqslant 5\cdot 10^6

思路

明显是dp问题,但不好想状态,利用 gcd\text{gcd} 具有的单调性,为了便于转移,考虑当前序列最后一个 g(i)g(i) 的值为dp变量。

考虑 f(i)f(i)a1,a2,,ata_1,a_2,\cdots, a_t 满足 gcd(a1,a2,,at)=g(t)=i\text{gcd}(a_1,a_2,\cdots,a_t)=g(t)=i 的序列的 StS_t 的最大值。所以每一个 f(i)f(i) 会确定至少一个长度为 tnt\leqslant n 的数列,满足 g(t)=ig(t) = i

cic_i 为含有因数 iiaja_j 的个数。

由于每一个 ii 可以通过 ipi\cdot ppp 为素数)转移过来(从数列上具体来说,是将因数为 ii 的数放在 f(ip)f(i\cdot p) 已有序列的末尾,重复的数字不变位置),最大值变化即

f(i)=maxpf(ip)+i(cicip)f(i) = \max_{p}f(i\cdot p) + i \cdot(c_i - c_{i\cdot p})

cicipc_i-c_{i\cdot p} 是为了避免重复计算相同因数 iif(i)f(i) 的贡献(因为在 f(ip)f(i\cdot p) 中已经计算过了,重复的数位置不变)。

初始化f(i)=icif(i) = i\cdot c_i(将以 ii 为因数的数排成一个数列)

先用 EulerEuler 筛预处理素数,便于状态转移时直接使用。

总复杂度:O(MlogM)O(M\log M)


CF1614 - Codeforces Round 757 (Div. 2)
https://wty-yy.github.io/posts/63615/
作者
wty
发布于
2021年12月13日
许可协议