20250828
奇怪的东西
函数 \(f(x)\) 满足 :
\[f(1)=1, \\ f(p^c) = \begin{cases} p^{114514}, & c=1 \\ p^{229028}(p+1)^{1919810(c-2)}, & c \geq 2 \end{cases} \]p 是质数, $c \geq 1$。 如果 \(\gcd(a, b)=1\) ,那么 \(f(a b)=f(a) f(b)\) 。
有一个长度为 \(n\) 的序列,第 \(i\) 项是 \(a_i\) 。有 \(q\) 次操作,操作分为两种。
1 x y,令 \(a_x \leftarrow y\)。2 x y,查询 \(\displaystyle f\left(\prod\limits_{x \le i \le y} a_i\right) \bmod 1019260817\)。强制在线。\(1 \le n, q \le 10^5\),\(1 \le a_i, y \le 10^6\)。5 s,1 GB。
以下假设 \(n, q\) 同阶。
对于 \(v \le 10^6\),至多有 \(K = 6\) 个不同质因数。每次修改需要考虑这 \(K\) 个质因数。
线性筛时记录每个数最小质因子的幂次。
\(O(n^{5/3}K^{1/3})\) 做法
想到 HDU 决斗,考虑分 \(B\) 块,直接维护块与块两两之间的答案。
- 单次 \(O(n / B)\) 修改某个颜色(质数)在大块的前缀和(出现次数)。
- 预处理每个质数的幂次,单次 \(O(n^2/B^2)\) 重新计算一个颜色对所有大块之间的贡献。
- 单次整块 \(O(1)\),散块 \(O(B)\) 查询。
由于前两条发生了 \(O(nK)\) 次,总复杂度 \(O(n^3K/B^2 + nB) = O(n^{5/3}K^{1/3})\)。调 + 卡一上午,TLE 了,和暴力老哥一样分(30pts)。
\(O(Kn\log^2n)\) 做法
转化成偏序问题,可以做到 n polylog。
令 \(k_1 = 114514, k_2 = 1919810\)。
不妨默认 \(f(x)\) 的每个 \(p^c\) 都取 \((p + 1)^{ck_2}\),然后对于 \(p\) 出现的第一次和第二次额外乘上 \(p^{k_1}/p^{k_2}\)。
前半部分可以直接树状数组做,就是 \(O(Kn\log n)\) 的。
后半部分对于每个 \(p\) 开 multiset 维护后继的后继,使用树状数组套动态开点线段树在线二维偏序,每次修改和查询都是 \(O(\log^2 n)\)。
这里因为第一次和第二次的额外贡献时相等的,所以只需要 \(l \le x \le r \land nxt(nxt(x)) > r\),并不需要额外考虑 \(nxt(x)\) 是否在区间内。
总复杂度 \(O(K n \log^2 n)\),且二位偏序每次修改有 6 倍常数,卡了一下午,TLE 了。
\(O(n\sqrt V + n\log^2 n)\) 做法
瓶颈在二维数点,考虑优化这部分。
考虑根号分治:小于 \(\sqrt V = 1000\) 的质数只有 \(168\) 个,近似 \(O(\sqrt V / \log V)\);大于 \(1000\) 的质数,每次出现,其次幂至多为 \(1\),且每次至多只有一个这样的质数。
对于小于 \(1000\) 的质数,每个质数开一个树状数组维护区间出现次数,查询时枚举这类质数,比较其出现次数与 \(2\) 的大小。这部分 \(O(n \sqrt V \log n / \log V)\),如果认为 \(\log n\) 和 \(\log V\) 是接近的,那么这部分复杂度 \(O(n \sqrt V)\)。
对于大于 \(1000\) 的质数,继续二维数点,复杂度降到 \(O(n \log n)\)。能够比较顺利地 AC。
CTT 2021 经典游戏
https://www.luogu.com.cn/problem/P8994
每个棋子独立,只考虑每个节点上棋子数量的奇偶性,设 \(v_x\) 表示 \(x\) 上棋子数量模 \(2\) 的结果。
确定根 \(r\) 后,设叶子高度为 \(0\),则 \(SG(x)\) 为 \(x\) 的高度 \(h(x)\)。为了让后手不能把异或和变为 \(0\),那么以 \(r\) 为根是合法的,当且仅当 \(h(r) < \bigoplus\limits_{v_x = 1} h(x)\)。
显然 \(SG(x)\) 只有至多两种取值,且只与以 \(x\) 为根时,原来的根位于 \(x\) 的哪个儿子的子树有关。
设 \(a_x\) 为 \(SG(x)\) 的最大值,\(b_x\) 为 \(SG(x)\) 的次大值,\(a_x\) 从与 \(x\) 相邻的 \(fr_x\) 转移得到。\(b_x\) 不能从 \(fr_x\) 转移。使用换根 DP 可以求出 \(a\) 和 \(b\)。
以 \(1\) 为根进行 DFS,求出每个点的 DFS 序。
\(v_x = 1\) 时:
- 若 \(fr_x = fa_x\),则 \(r \in subtree(x)\) 贡献为 \(a_x\),在子树外贡献为 \(b_x\);
- 否则 \(fr_x\) 为 \(x\) 的儿子,\(r \in subtree(fr_x)\) 贡献为 \(b_x\),否则贡献为 \(a_x\)。
使用树状数组可以完成单点修改单点查询。特判掉 \(fa_x\) 和 \(fr_x\),剩下 \(x\) 的一些儿子 \(y \ne fr_x\)。
从 \(x\) 换根到 \(y\) 时,对其它节点而言,根的方向都没有发生改变,\(x\) 的贡献没有改变。
若 \(v_y = 1\),则从 \(x\) 换根到 \(y\) 产生贡献 \(a_y \oplus b_y\)。因为 \(fr_x \ne y\),所以 \(a_y \ge a_x + 1\)。而如果 \(fr_y \ne x\),则 \(a_x \ge a_y + 1\),矛盾。所以 \(fr_y = x\),\(a_y = a_x + 1\),原先贡献 \(b_y\),新的贡献 \(a_y\)。
对每个 \(x\) 使用 01Trie 维护换根到其非 \(fr_x\) 儿子的贡献(若该儿子没被启用则为 \(0\)),异或上 \(x\) 本来的答案,数有多少个大于 \(a_x\) 的即可。
括号序列
定义只由 (和) 组成的序列为括号序列。
定义一个括号序列是合法的,当且仅当它的任意一个前缀满足(的数量不少于)的数量,且整个序列中(和)的数量是相等的。
定义一个括号序列是好的,当且仅当存在两个并为整个序列的子序列,使得每个子序列都是合法的括号序列。
现在,给定一个长为 \(n\) 的括号序列。有 \(q\) 次询问,每次询问给定一个区间 \([l, r]\) ,你需要求出 \([l, r]\) 有多少个子区间是好的括号序列。
\(1 \le n, q \le 3 \times 10^5\)。
括号序列合法当且仅当:(为 \(1\),)为 \(-1\),任意前缀和 \(\ge 0\),任意后缀和 \(\le 0\)。
两组括号序列叠加,出现 \(2\) 次的(为 \(2\),出现 \(1\) 次的(为 \(1\),右括号同理。则仍满足任意前缀和与后缀和的要求。
定理:括号序列好的当且仅当:(为 \(2\),)为 \(-1\),任意前缀和 \(\ge 0\);(为 \(1\),)为 \(-2\),任意后缀和 \(\le 0\)。
必要性:前半部分条件对原来只加不减,后半部分条件对原来只减不加,显然仍满足。
充分性:先按(为 \(2\),)为 \(-1\) 得到序列,总和为 \(k \ge 0\),把后 \(k\) 个全部 \(-1\) 得到总和为 \(0\) 的序列,不难验证满足任意前缀和与后缀和的要求。将 \(2\) 和 \(-2\) 同时给到两边,\(1\) 给少的,\(-1\) 给多的,两边之差绝对值 \(\le 1\),任意时刻前缀和都不会 \(< 0\),能还原出好的括号序列。
拿个单调栈搞一下每个左括号和右括号最长能延伸到哪里,扫描线一下即可。

浙公网安备 33010602011771号