Codeforces Round #814 (Div. 1)
A Burenka and Traditions
首先可以发现可以只执行区间长度为 1 或者区间长度为 2 的操作。如果全部用长度为 1 的操作,需要操作 n 次,而对一个异或和为 0 的区间,可以
每次操作相邻的两个数,这样会少 1 次操作次数。于是只需要去找异或和为 0 的区间,用 set 记录前缀异或和并支持查询即可。
B Fibonacci Strings
首先根据所有数的总和确定需要分前多少个 fib 数,然后贪心,从大到小依次考虑每个 fib 数,每次取出剩下的数中的最大值,如果是上次操作的
则取次大值,如果这个数小于需要操作的 fib 数则无解,否则将它减去当前的 fib 数再放回去。
这是因为如果剩下的某个数大于现在需要分的 fib 数,那么要把它分解成若干不相邻的 fib 项之和,这个分解方法里面是一定包含当前的这个 fib 数的,所以这一步一定要分出去,否则后面就分不完了。
C Tonya and Burenka-179
如果对 \(n\) 的每一个约数 \(d\) 都维护所有大小为 \(d\) 的环的数字总和的话,时间复杂度是 \(O(nd(n)\log n)\) ,过不去。想一下可以发现如果
两个约数 \(d_1,d_2\) 满足 \(d_1\) 是 \(d_2\) 的约数,那么只用维护大小为 \(d_1\) 的环的信息即可,时间复杂度 \(O(n\omega(n)\log n)\) 。
D Permutation for Burenka
首先根据序列 \(p\) 建出笛卡尔树,就等价于在树上填数,使得 \(a_x\) 大于 \(x\) 子树中的其他任意一个点的 \(a\) 。
在填数时,只需要考虑初始已经存在的数对当前位置的大小限制,因为后面填的数可以通过交换来满足彼此之间的大小关系,于是可以对每个需要填的位置处理出 \([l_i,r_i]\) 表示这个位置能填的数的区间。
那么问题转化为给出 \(k\) 个区间,需要验证 \(S\) 中的 \(k-1\) 个数以及 \(d\) 能否与这些区间形成一个合法的匹配。先不考虑 \(d\) ,尝试匹配 \(S\) 中的 \(k-1\) 个数。将这些数从小到大排序,将 \(k\) 个区间按照左端点排序,依次考虑每个数,并且将所有左端点 \(\le\) 当前数的区间加到一个 multiset 中,每次在 multiset 中查询出右端点 \(\ge\) 当前数的最小右端点的区间,将其与当前的数匹配。
记第 \(i\) 个点匹配到的区间为 \(seg(i)\) ,最后会剩下一个区间没有匹配到,记作 \(seg(k)\) 。记 \(dp(i)\) 表示去掉第 \(i\) 个区间后,剩下的 \(i-1\) 个区间是否能与 \(S\) 中的 \(k-1\) 个数形成合法匹配。初始有 \(dp(seg(k))=1\) ,再从 \(k-1\) 开始,从大到小枚举 \(i\) ,记 \(nxt(i)\) 表示如果去掉 \(seg(i)\) ,第 \(i\) 个点会匹配到的区间,这个可以在计算 \(seg(i)\) 时一并求出。那么如果 \(nxt(i)\) 存在,就有 \(dp(seg(i))=dp(nxt(i))\) ,否则 \(dp(seg(i))=0\) 。最后所有 \(dp\) 值为 \(1\) 的区间形成的并就是合法的 \(d\) 的所有取值。由于第 \(i\) 个点既能匹配 \(seg(i)\) ,又能匹配 \(nxt(i)\) ,所以这两个区间一定是相交的,那么最后所有 \(dp\) 值为 \(1\) 的区间并起来一定还是一个区间,记录这个区间的左右端点即可。没有注意到这个性质的话,也可以直接通过打差分标记求出这些区间的并。时间复杂度 \(O(n\log n)\) 。
E Impressionism
将所有行看成 \(n\) 个点,将所有列看称 \(m\) 个点,对于每个 \(a_{i,j}\) ,将行 \(i\) 与列 \(j\) 之间连一条边,颜色为 \(a_{i,j}\) ,那么问题就转化为了判断两张二分图是否同构。
由于两条颜色相同的边不会有公共点,所以对于一个连通块,只需要完成了一个点的配对,就可以沿着边将所有点的配对情况都依次确定。最后根据配对的情况分别对行与列构造一个交换顺序即可。
F Burenka, an Array and Queries
先莫比乌斯反演一下,可知要求的是 \(\sum_{d|p} \mu(d)\cdot \lfloor \frac{C}{d}\rfloor\) 。这个值只和区间 \([l,r]\) 中所有数含有的质因子有关,可以通过莫队求出每次询问时区间内含有的所有质因子。
现在考虑已知了区间内含有的所有质因子,如何求出答案。注意计算时只会用到没有重复质因子并且 \(\le C\) 的 \(d\) ,而 \(43\times 47\times 53=107113>10^5\) ,于是可以将 \(2\times 10^4\) 内的所有质数分为 \(<43\) 的小质数(共 \(13\) 个),与 \(\ge 43\) 的大质数(共 \(2249\) 个),那么有用的 \(d\) 所包含的质因子一定是由所有小质数的一个子集与不超过 \(2\) 个大质数组成的。于是还要找出乘积不超过 \(10^5\) 的大质数对(共 $4904 $ 个)。
预处理出 \(f(S)\) 表示选取的小质数为 \(S\) 的各个子集的答案之和,\(g(S,x)\) 表示选取的小质数为 \(S\) 的各个子集,选取的大质数为 \(x\) 的答案之和,\(h(S,x,y)\) 表示选取的小质数为 \(S\) 的各个子集,选取的大质数为 \(x\) 与 \(y\) 的答案之和,回答询问时枚举选取的大质数或大质数对即可求出答案。时间复杂度为 \(O(n\sqrt n+qk)\) ,其中 \(k\) 为合法的大质数与大质数对的数目之和,在本题的数据范围下为 \(7153\) 。