退役前的做题记录4
基本没写什么题目,考试考到自闭。
COGS:疯狂的字符串
设 \(f_i\) 表示第一次匹配为 \([i-k+1,i]\) 的方案数,大概要写一个 \(kmp\) 预处理
这个转移可以构造成卷积的形式,求逆即可
CodeChef:Sum of Cubes
考虑组合意义,大力分类讨论即可。
Codeforces GYM101237 C:The Palindrome Extraction
中间的回文串一定最长,每次倍增跳 \(sam\) 就好了,\(O(nlogn)\)
Codeforces 997C:Sky Full of Stars
容斥行套容斥列,可以利用二项式定理优化成 \(nlogn\)
Codeforces 757G:Can Bash Save the Day?
详见 HNOI2015开店,这道题每次只会影响一棵主席树的值,暴力重构即可。
BZOJ3489:A simple rmq problem
设每个数字位置 \(i\),上一次出现位置 \(l\),下一次为 \(r\),那么所有询问左端点在 \([l,i]\) 和右端点在 \([i,r]\) 都要对 \(a_i\) 取 \(max\)。
矩阵取 \(max\),单点查询,直接上二维线段树。
魔力环
先套一个 \(polya\),\(ans=\frac{\sum_{d|n}f(d)\varphi(\frac{n}{d})}{n}\)
其中 \(f(x)\) 表示 \(x\) 个大小为 \(\frac{n}{x}\) 的环的合法的不动点的个数。
首先一个优化,\(\frac{n}{d}\) 必须是 \(m\) 的约数,否则是不行的。
现在的问题变成快速求把 \(n\) 个相同的球放进 \(m\) 个不同盒子或者摆在前面或后面,使得每个盒子的个数以及前后的和不超过 \(k\)。
枚举前后放多少个,中间的用生成函数,就是:\([x^n]\sum_{i=0}^{k}(i+1)x^i(\sum_{i=0}^{k}x^i)^{m}\)
对于前面的 \(\sum_{i=0}^{k}(i+1)x^i\),可以运用简单求和的技巧变成
对于后面的,就是
整合起来
下面的 \((\frac{1}{1-x})^{m+2}=(\sum_{i=0}x)^{m+2}\),就是个组合数 \(\sum_{i=0}\binom{m+1+i}{i}x^i\)。
上面的 \((1-x^{k+1})^{m}\) 暴力展开,就是 \(\sum_{i=0}^{m}(-1)^ix^{i(k+1)}\binom{m}{i}\)。
而 \(1-x^{k+1}(k+2)+x^{k+2}(k+1)\) 是一个三项的东西,暴力枚举算每一项即可。
所以直接 \(O(\frac{n}{k+1})\) 枚举即可算出 \(f(n)\)。
设 \(\sigma(x)\) 表示 \(x\) 的约数和,是 \(xlnx\) 级别的。
复杂度就是 \(O(\frac{\sigma(gcd(n,m))}{k+1})\)。
LOJ510:「LibreOJ NOI Round #1」北校门外的回忆
询问操作显然是 \(log_kn\) 的。
修改操作的每一步实际上是最低非零位乘 \(2\) 并进位。
当 \(k\) 为奇数的时候,它的这一位不会变成 \(0\),如果 \(x\) 向 \(x+lowbit(x)\) 连边,一定会形成若干条链,因为 \(2\) 在 \(k\) 为奇数的条件下存在逆元,所以每个点的前驱后继一定唯一。
当 \(k\) 为偶数的时候,就有可能这一位变成 \(0\),\(x\) 能够变成 \(0\) 的条件就是 \(lowbit(x)\times 2^y=k\)。
而对于 \(lowbit(x)\) 的 \(2\) 的质因子个数不少于 \(k\) 的 \(2\) 的质因子个数的 \(x\),一定也会形成若干条链,\(2\) 在弄去 \(2\) 之后的 \(k\) 意义下还是有逆元。
那么一个数字暴力跳到链上的复杂度就是 \(log_2klog_kn=log_2n\)。
所以只要维护每条链就好了。
对于 \(n\le 10^9\) 的范围,显然不能暴力维护链。
不难发现,确定了一条链的首部就唯一确定了这条链,所以现在的问题就是怎么样快速找到 \(x\) 最终跳到的链的链首。
\(x\) 如果不在链上就暴力跳到链上就好了 \(log_2n\)。
在链上由于 \(lowbit\) 的位置不变,所以只要倍增这一位就好了。
大下标用动态开点线段树处理。
BZOJ2741:【FOTILE模拟赛】L
前缀和之后就变成了区间选两个数。
分块,预处理每个块的右端点到每个点的答案,暴力查询即可。
\(O((n+m)log(2^{31}-1)\sqrt{n})\)
Codeforces 543E:Listening to Music
空间有点卡,考虑分块。这个分块简直有毒
考虑 \(a_i\) 从小到大排序,那么每一次都会让一个区间 \(+1\)。
考虑把主席树做的事情用分块存储,每 \(\sqrt{n}\) 个操作分一块。
之后由于要对序列操作,所以再对序列分块。
可以预处理这样几个东西:
\(mn_{i,j}\) 表示前 \(i\) 个块的操作后,序列块 \(j\) 的最小值。
\(st_{i,j}\) 表示前 \(i\) 个块的操作后,序列块 \(j\) 的左端点的值。
\(pmn_{i},smn_{i}\) 分别表示第 \(i\) 次操作后,所影响的序列左右非整块的最小值。
预处理可以通过对块打标记做到 \(O(n\sqrt{n})\)。
对于询问 \(l,r,x\):
取出 \(x\) 前面的整块的预处理的东西。
然后枚举非整块的操作进行修改,对于序列中的整块可以差分(更新块首元素),对于边角的块用预处理的 \(pmn,smn\) 更新。
然后查询,对于序列的整块可以直接用整块的 \(mn\),对于非整块可以用块首元素推出这个块的每一个点。
这一部分复杂度 \(O(m\sqrt{n})\)。
总复杂度 \(O((n+m)\sqrt{n})\)。
Luogu 卡常者π酱
\(SAM+DP\) 单调队列优化,计算一个点的往后能匹配最长的串的时候可以利用从上一个点的信息。
Luogu 你祖宗π酱
不难发现第一问的答案 \(ans_1\) 就是:
设中序遍历中 \(1\) 和 \(x\) 的位置为 \(p_1,p_2\),如果 \(p_1<p_2\) 则 \(ans_1=n-p_2+1\)。
否则 \(ans_1=p_2\)。
第二问的上界显然是 \(ans_1+x\) 的深度,注意到 \(x\) 到根的路径上如果存在一个不是答案的点就一定要付出 \(1\) 的代价,其它情况均可以通过由浅到深依次完成。
所以最优应该是 \(ans_1+x\) 到根的路径上非答案点的个数。
Codeforces 833E:Caramel Clouds
考虑离线。
按照时间顺序添加或者删除云,用 \(set\) 维护。
如果 \(set\) 中没用东西,那么直接加上这里的时间。
如果有一个,更新它覆盖的长度。
如果有两个,更新两个共同覆盖的长度,注意到只有 \(O(n)\) 组这样的东西,\(map\) 记录。
如果大于等于三个,不用管。
只选一个的很好维护。
然后还要维护选择两个的,只需要开一个权值线段树每一次查询最大值更新每个最大可以选的长度即可。
抄yyb的代码吧
多项式三角函数
那么
同理
所以
注意到
而 \(-1\) 存在二次剩余 \(86583718\) 和 \(911660635\)。
带入之后 \(exp\) 即可。
不知道有什么用。
多项式反三角函数
不知道有什么用。