比赛链接
C. Divan and bitwise operations
题意
存在一个长度为 n 的正整数序列 {ai},m 个限制条件,每个限制条件由 l,r,x 构成,表示 {ai} 在区间 [l,r] 中的元素或运算值为 x。对于任意一个满足该条件的序列,求该序列的所有子序列的异或值之和,结果对 109+7 取模。
数据范围:1⩽n,m⩽2⋅105。
思路
开始自己从每一位 ai 的取值去想的,结果发现根本无法求出所有子序列的异或值之和,看了题解才发现这题巨妙(
既然不容易求出每个子序列然后进行异或再求和,那就直接考虑异或运算下的子序列对答案的贡献。
考虑二进制位的第 i 位,如果所有的 x 或起来这一位都是 0,那么就不存在 aj 的第 i 为 1,
现在考虑存在第 i 位为 1 的 aj,令集合 A 为所有 aj 第 i 位为 0,B 为所有 aj 第 i 位为 1,则 ∣A∣+∣B∣=n,
直接从子序列角度分析,一个子序列可以视为分别从集合 A 和集合 B 中取出元素,按照原有顺序,构成子序列,所以一个子序列的第 i 位异或值为 1,当且仅当,它选取了奇数个 B 中的元素,也就是
∑=(1∣B∣)+(3∣B∣)+⋯+(k∣B∣)
如果 ∣B∣ 为奇数,则 k=∣B∣,否则 k=∣B∣−1。利用二项式系数的递推式,可以得到
∑=(0∣B∣−1)+(1∣B∣−1)+(2∣B∣−1)+(3∣B∣−1)+⋯+(∣B∣−1∣B∣−1)=2∣B∣−1
于是第 i 位为 1 的子序列个数为
2∣A∣⋅∑=2∣A∣⋅2∣B∣−1=2∣A∣+∣B∣−1=2n−1
故,无论 A,B 中元素如何,只要 B=∅,第 i 位为 1 的子序列的个数都为定值 2n−1。
B=∅ 等价于所有 x 或起来第 i 位为 1,那么对所有子序列求和,答案就是
2n−1⋅i=1ORmxi
点击显/隐代码
D1. Divan and Kostomuksha (easy version)
题意
给出一个序列 {ai},可以对该序列进行重排,求重排后
Sn=i=1∑ngcd(a1,a2,⋯,ai)=:i=1∑ng(i)
的最大值。
数据范围:1⩽n⩽105,1⩽ai⩽5⋅106
思路
明显是dp问题,但不好想状态,利用 gcd 具有的单调性,为了便于转移,考虑当前序列最后一个 g(i) 的值为dp变量。
考虑 f(i) 为 a1,a2,⋯,at 满足 gcd(a1,a2,⋯,at)=g(t)=i 的序列的 St 的最大值。所以每一个 f(i) 会确定至少一个长度为 t⩽n 的数列,满足 g(t)=i。
令 ci 为含有因数 i 的 aj 的个数。
由于每一个 i 可以通过 i⋅p(p 为素数)转移过来(从数列上具体来说,是将因数为 i 的数放在 f(i⋅p) 已有序列的末尾,重复的数字不变位置),最大值变化即
f(i)=pmaxf(i⋅p)+i⋅(ci−ci⋅p)
ci−ci⋅p 是为了避免重复计算相同因数 i 对 f(i) 的贡献(因为在 f(i⋅p) 中已经计算过了,重复的数位置不变)。
初始化: f(i)=i⋅ci(将以 i 为因数的数排成一个数列)
先用 Euler 筛预处理素数,便于状态转移时直接使用。
总复杂度:O(MlogM)
点击显/隐代码