2025.2
2025.2
P1587
首先我们要枚举的一定是互质的二元组,然后又因为在 \(k\) 进制下是循环小数,所以答案即为:
交换循环顺序,套路使用莫比乌斯反演化简式子:
等式右边相当于 \(S({\frac m d}, n, d)\) ,所以可以直接递归计算:
P6624
前面套路反演,即求:
枚举 \(d\) ,现在要求:
我们把每个元素换成多项式 \(i + w_{e_i}x\) ,我们直接把多项式乘起来,答案就是一次项系数。直接做是单次 \(O(n^4 \log n)\) 。
但是我们发现我们只关系前两项,所以只保留常数项和一次项即可。
P6292
先想一个经典问题「静态区间不同元素种类数」怎么做。
我们可以考虑扫描线。固定右端点,我们只考虑一种元素最后出现的位置。
每次移动端点 \(i - 1 \to i\) 时,我们贪心把 \(a(i)\) 上次出现的位置 \(-1\) ,当前为 \(+1\) 。这样区间 \([l,i]\) 的答案就是区间和。
回到这道题。我们视「相同子串」为「相同元素」。每个子串 \(S[l,r]\) 在左端点贡献权值。每当我们移动端点 \(i-1 \to i\) 是,我们考虑所有子串 \(S[l, i]\) ,在上次出现位置 \(-1\) ,在当前位置 \(+1\) 。
我们发现 \(+1\) 操作可以直接使用线段树维护,相当于前缀 \(+1\) 。
我们现在考虑如何快速进行 \(-1\) 操作,瓶颈在于找到 \(S[l,i]\) 上次出现的位置。找相同子串可以使用 SAM 快速维护。我们对原串建出 SAM 后,设 \(p(i)\) 为 \(S(i)\) 在 SAM 上的位置。
所有根到节点 \(p(i)\) 的路径即为所有子串 \(S[l, i]\) 。我们还发现,所有子串 \(S[l, i]\) 上次出现的位置的是若干段连续的区间,并且在 SAM 的 fail 树上。
我们每次修改相当于往上访问 \(p(i)\) 的一个祖先 \(fa(k)\),对 \(fa(k)\) 所对应的区间进行区间 \(-1\) 。
我们发现,每次修改完以后,这两个区间合并成了一个新的区间(即最后出现的位置都变成了 \(S[1,i]\) 的后缀)。这不就是 LCT 的 access(x) 操作吗?我们直接上 LCT 用重链维护一个连续区间,时间复杂度为 \(O(n \log^2 n + q \log n)\) 。
P7342
问题是求 \(n\) 次给定 \(A_0, A_1, A_2, \dots, A_{m - 1}\) ,那么对应的 \(2^t\) 个表达式的值是多少。
先建出表达式树。枚举最后的答案是 \(a(i)\) 。设 \(f(x, 0/1)\) 表示以 \(x\) 为根的子树所对应的表达式的值 \([\ge a(i)]\) 的情况数。
我们如果枚举最后的答案是 k 。确定了一个集合 \(S\) 表示比 \(k\) 小的集合,\(\bar{S}\) 就是大于等于 \(k\) 的集合。我们发现如果确定了这样的大小关系,我们可以二进制枚举 \(< a(i)\) 的位置,所对应的 ? 的情况是一样的。
计算结果小于/大于等于的情况数可以直接转移:
最后答案差分一下 \(S\) 和 \(S / \{j\}\) ,总的时间复杂度为 \(O(2^m|E| + poly(n))\) 。
P2791
容易列出式子:
我们考虑组合意义:相当于在前 \(m\) 个盒子取 \(i\) 个盒子,在后 \(n - m\) 个盒子中取 \(k - i\) 个盒子,在给 \(L\) 个球放入这不同的 \(i\) 个盒子。
“放入盒子” 考虑第二类斯特林数,\(i ^ L\) 可以先将 \(L\) 个球放入 \(j\) 个互不区分的盒子,再从 \(i\) 个盒子中选出 \(j\) 个,每个盒子顺序可以任意:
带入后交换枚举步骤:
右边的三个组合数不好直接做。组合意义是:从前 \(m\) 个小球取 \(i\) 个小球,在后 \(n - m\) 个小球中取 \(k - i\) 个小球,在从 \(i\) 个小球中选出 \(j\) 个。
相当于从前 \(m\) 个小球中先选出 \(j\) 个,再重剩下的 \(m - j\) 个小球中选出 \(i - j\) 个,最后从剩下 \(n - m\) 个小球选出 \(k - i\) 个。所以可化为:
右边是范德蒙卷积,所以就是:
使用多项式算出 \(S(L, i)\) 即可解决这道题。
qoj 9727
二进制先拆位,发现三个操作分别为区间覆盖为 \(0/1\) 、单点修改、查询删去一个点后区间是否全为 \(1\) 。
我们贪心的考虑这个询问,优先满足贡献大的位。注意到一个位可能产生贡献当且仅当区间中 \(1\) 的个数为 \(len\) 或 \(len - 1\) 。
我们可以用 \(dat1\) 和 \(dat2\) 维护这个区间是否有 \(len\) 个 \(1\) 或 \(len - 1\) 个 \(1\) 。我们能快速使用线段树维护这个事情。每次修改操作可以直接修改
对于每次查询,我们找到最大的 \(dat1\) 和 \(dat2\) 不相同的位,用线段树二分找到要修改的位置。然后直接查询即可。
我们发现所有操作都能写成 与、或、异或 之类的操作,所以我们可以直接使用 long long 代替 \(O(\log V)\) 棵线段树。总的时间复杂度为 \(O((n + m) \log n)\) 。
qoj 9243
计数。先考虑 \(p(S)\) 实际上在干什么。实际上就是 \(\binom{|S|}{cnt_1, cnt_2, \dots, cnt_n}\) 。先考虑 \(p(S)\) 为奇数的情况。我们用 lucas 定理的经典结论发现 \(cnt_i\) 在二进制下两两不交。
现在考虑如何求出 \(f(n, X, Y)\) 。因为 \(cnt_i\) 两两不交,所以在二进制下不会发生进位。
现在我们可以枚举一个数字 \(a_i\) 满足 \(Y\) 的限制。再考虑 \(n\) 的限制,假设 \(cnt_i\) 的第 \(t\) 位为 \(1\) ,则对 \(x\) 的贡献为 \(2^t \times a_i\) 。
现在相当于对 \(O(\log n) \times O(\log Y)\) 的矩阵 \(G\) 计数。矩阵中每一个 \(G_{i, j}\) 会对 \(X\) 贡献 \(2^{i+j}\) 。然后可以使用数位 dp 对 \(x\) 计数。设 \(f(t, S, x)\) 表示满足前 \(t\) 位,对 \(Y\) 的贡献为 \(S\) ,进位为 \(x\) 。每次转移枚举 \(i, j\) 即可。最后 FMT 回每个 \(Y\) 统计答案。

浙公网安备 33010602011771号