[笑死人] 笑死人
上午
ZJOI2020 密码
给定 (p) 级别在 (10^{18}) ,有一个未知数 (x) ,会给 (a_ix\pmod p) ,但有 ([-10{16}/2,10/2]) 的误差。误差之间独立且随机。(x,a_i) 随机。
方法 1
一个条件相当于是 (L_i\le a_ix\le R_i) ,尝试联立两个方程。
设 (y=a_1x) ,那么推推推可以推出形为这样的不等式:
[L_1\le y\le R_1\ L_2\le Ay%p\le R_2 ]
魔改扩欧可以得到下面的最小整数解,然后???
把第一部分分块,对于一块 (y\in [L_1,L_1+T-1]) 和它的下一块,那么对于第二部分就是整体加了 (AT%p) ,所以把 (Ay%p) 排序之后就可以通过二分求出所有解。
在 (err) 较小((10^{11}))的时候解不会太多,暴力判断即可。
方法 2
考虑如果 (a) 较小,那么 (L_i\le a_ix\le R_i) 这样的方程的解可以被分成 (a) 段。
所以尝试让 (a) 变小。(???)
选 (k) 条方程,给每一个方程带一个 (\pm1) 的系数,加起来。此时 (err) 的数量级不会变大(乘一个小常数?)。
所以可以选一些方程加起来,尝试把 (a) 变小。
([0,1]) 内随机 (k) 个实数,两两差的最小值期望 (O({1\over k^2})) (经典结论,可以理解为生日悖论)。
大力随机即可获得不错的分数。
(a) 变小之后可以解出若干区间,然后多搞出几个 (a) 就可以把很多组区间求交,然后就可以暴力了?
正解
上面减小 (a_i) 的尝试有些类似于卡哈希。
Tree Attack !
对于一个序列 ({a}) ,每次排序之后选相邻的项的差,即可使得每次 (n=n/2) , (\max a=\max a/n) ,且每个 (a) 的系数都是 (\pm 1) 。
在这一题中 (m) 不够大,但是系数也不一定必须是 (0,\pm 1) ,所以可以加入各种奇怪操作。
还有 multi tree attack ……
ZJOI2020 序列
线性规划
就是把一个数的贡献分成两部分,一个是连续的,一个是跳的,然后跳的最小操作次数也可以把奇偶分开做,所以就是线性规划,转一手对偶就做完了……
上面的图略有一些笔误,转对偶之后是最大化 (\sum_i (-a_i)u_i+\sum_i (a_i-a_{i-2})w_i) 。
至于为什么取值都是整数呢?操作一下转成费用流即可证明。
怎么转成费用流?注意到 (v_i,w_i) 只在两个不等式中出现,所以可以看做连点之间的边;而 (u) 可以看做 (S) 连向点的边或点连向 (T) 的边。费用对应上去即可。
贪心
从左往右考虑。先考虑最左边两个。
可以发现,只要 (a_1>0,a_2>0) ,那么必然有从 1 开始的连续减一线段,且长度至少为 2 。如果没有那么可以通过调整使得有。
到最后 (a_1=0) 或 (a_2=0) 。如果 (a_1=0) 那么直接继续,否则会有从 1 开始跳着减 1 。
然后考虑 2 和 3 ,我们想要用同样的方法贪心,但是有一个问题:有一些操作可以连到 3 ,它们可以继续往前连。
设连到 3 的有 (A) 个连续的, (B) 个跳的。先让 (A,B) 都对 (a_3) 取 (\min) 。
如果 (A+B\le a_3) ,那么容易发现把它们全部保留下来是最优的,然后情况和 (a_1,a_2) 一模一样,照着做即可。
否则,设 (k=A+B-a_3) 为多余的操作数,显然有 (k\le A,k\le B) 。
多余的看起来很不爽,所以令 (A=A-k,B=B-k) ,那么 (A,B) 都要保留,并且还可以往前连 (k) 个免费的任意种类。
此时 (A,B,a_3) 都消失了,留给 (a_2) 的唯一方案是往前连跳的。
然后为了表现出 (a_3) 这里有免费边,把 (a_3) 置为 (k) ,答案减去 (k) 。
ZJOI2020 抽卡
我们先转化题意。
先转化题意。
这种随机抽卡的题,可以考虑每一个没有达成目标状态的集合,同样大小的集合走到的概率和期望呆在这的时间是一样的,所以就转化成了数每一个大小的不合法集合的个数。
然后考虑怎样 dp 这个东西。可以设 (dp_{i,j}) 表示考虑了前 (i) 张牌,选了 (j) 张的方案数,然后转移是 (dp_{i,j}=dp_{i-1,j-1}+dp_{i-1,j}-[ok]) 。其中 ([ok]) 为 (dp_{i-k-1,j-k}) ,或在 (i=k) 时为 (dp_{i-k,j-k}) ,或前面不连续的时候是 0 。
对于 (f_i=a\times f_{i-1}+b\times f_{i-k-1}) 有 (O(n/k)) 的做法:其实就是看做走路,然后枚举 (k+1) 步的走了几次,然后组合数算方案数即可。
容易看出上面的 dp 也是这样的形式: (dp_i=(x+1)dp_{i-1}-x^k dp_{i-k-1}) 。
把式子列出来之后可能可以分治 NTT 。
式子(连续的一段,不连续的只需要最后分治乘起来就行了):
[F_{m}=\sum_{i=0}^{\lfloor m /(k+1)\rfloor}\left(-x{k}\right) (x+1)^{m-i(k+1)} \left(\begin{array}{c} m-i k \ i \end{array}\right) ]
同样是分治,本质上和上面那东西没什么区别。
好像 (dp_{k,k}) 被减掉的 1 还要额外做一遍?
PE437
显然可以转化为求 (f_k=\sum [最长段\le k]) 。
这东西显然有 (dp_i=n\times dp_{i-1}-(n-1)\times dp_{i-k-1}) ,然后用 (O(n/k)) 算这个东西的方法就可以做了。
复杂度 (O(n\log n)) 。
EC Final 2019 J
显然应该从小往大往里面加数,考虑每个数能去哪里。
序列里面会有一些线段,表示线段里面的数“基本”可以随便移动。
加入一个数的时候,如果不在任何一个线段里,那么它显然位置永远不会变化,而是会带来两个新的线段(左右各一个)。如果线段相交了那么会合并。
否则,它可以在已有的线段里面移动,然后还可以把这个线段往两边扩展。注意不管怎么扩展都不会覆盖到确定动不了的点。
所以一个点加入的时候就可以确定它到底可以走到哪里:原有的线段里。而它的位置不能和别的点重合,所以方案数是 (len-cnt) ,其中 (cnt) 是之前就已经确定要在这个线段里的点的个数。
下午
保序回归
要求:代价函数 (f_i(x)) 是凸的。
考虑
\(\[\sum_i f_i(x_i)=C+\sum_i\int_0^{x_i} f_i'(y)\mathrm{d}y=C+\int_0^{\infty}\sum_i [x_i\le y]f_i'(y)\mathrm{d}y \]\)
所以如果对于每个 (y) 用最小权闭合子图求出 (\sum_i [x_i\le y]f_i'(y)) 的最小值,积分起来,就得到了答案的一个下界。至于为什么能取到这个下界与函数凸性有关,不会证。
但是其实没有必要这么做,只需要整体二分一个 (y) ,跑最小权闭合子图,就可以知道哪些点较小,哪些点较大,然后分治两边。分治的时候不在这个区间的点可以直接和 (S) 或 (T) 缩起来,保证复杂度。
要求整数的时候就是把求导改成差分。
保序回归
要求:代价函数是凸的。
对于每一个 (\lambda) ,看哪些点小于它,哪些大于它。如果大于它则贡献是 (f'_i(\lambda)) 。跑最小权闭合子图。
然后整体二分。
正确性感性理解。求出来的显然是下界,至于为什么取得到就不管了……
泡泡糖
在权值只能是 ({0,1}) 的时候可以轮廓线 DP 。
对于更大的情况基本上就是保序回归的整体二分思路。同样不会证明正确性。
run
称一个极长的周期串(周期 $\le $ (|s|/2) )为一个 run 。
一个字符串的 runs 的个数是 (O(n)) 的。
怎么求?……
本原平方串
可以被写成 (AA) 的形式,且最小循环节恰好是 (|s|/2) 。
每个位置开头的本原平方串的个数是 (O(\log n)) 的。
证明?……
ZJOI2020 字符串
把一个串中一个平方串的第一次和最后一次出现称为关键串。(不一定本原)
如 aabaabaabaabaabaaba 中的 aabaab,abaaba,baabaa,aabaabaabaab,...
关键串个数是 (O(n\log n)) 的。
询问时答案“基本”是不同的关键串。
第一点的证明:
如果只循环两次,那么显然是 (O(n\log n)) 的。
对于非本原的,掉线了……
可以和本原平方串对应起来?
一个串中本质不同平方串=本质不同关键串?
掉线快乐?
Another Chess Problem
看到这个图可能会更明确一些:
发现这个题做过,就做完了 /fad
EC Final 2019 K
给了一个多边形的三角剖分,边有边权,无向,求两两之间的最大流之和。
最大流转最小割,然后转成对偶图最短路。
三角剖分图的对偶图是一棵树(把外面无穷大平面拆成 (n) 个叶子)。
Gomory-Hu Tree 是两两最小割的最小生成树。
此时的最小割是某两个叶子的路径长度。
考虑求出叶子组成的完全图的最小生成树。boruvka 或别的神仙东西。
可以发现如果把最小生成树画在图上,不会相交(???)。
并且此时图也有不错的性质,可以求出 kruskal 重构树(即“对偶”回去),就可以方便地求出两个点的最小割了。
其实就是两点的最小割就是找到能把它们分开的一对叶子,也就是路径上的最小边。
然而 dls 不记得怎么处理相交的情况了,……
方法 2
同样是转成对偶图。
考虑凸包上的边权最小的边,那么如果有一个最短路走到了它旁边的三角形对应的点,就一定会从这里走出去。
所以可以把这条边删掉,合并它对应的叶子节点和三角形节点,然后把删掉的边权加到三角形的另外两条边上。此时那两条边变成了边界上的边。
如果这条边删掉之后删透了,那么就是得到了 gomory-hu tree 上面的一条边。
怎么实现?把删边的过程记下来,倒过来变成加边,那么就是合并两个连通块了。
EC Final 2019 B
一次走两步,就比较好做了。
Junk Problem
如果是两两和不同,那么可以构造这么个集合: ({i\times 2p+i^2%p}) 。
然后瞬间掉线……
对于异或,把高低位拆开,假设各有 (n) 位,那么造一个 (n) 阶不可约多项式 (P(x)) (于是有逆元(不过常数项为 0 也能有逆元?),有一些性质),然后低位随便放,可以对应到一个 (f(x)) ,那么高位就用 (f^3(x)\pmod P) (显然也是模 2 意义下)。
考虑怎样会相等。以下乘法都是模 (P) 模 2 的多项式乘法。
由于 (a3-b3=(a-b)(a2+ab+b2)) ,所以可以拆开一些东西。
然后因为是模 2 意义下,所以加减等价,所以证明相乘相等。
然后因为是个域(??),所以有唯一分解(??),就可以证明如果两对东西相加相等则两两相等。
最后如果上界不是 (2^{2n}-1) 怎么办?
好像是取最近的那一边乱搞。
由于模 (P(x)) ,所以一个非 0 多项式不管常数项是否为 0 都有逆元。
在线 O(1) 逆元
复杂度为 (O(p^{2\over 3})-O(1)) 。
设一个阈值 (M) ,对于一个 (a) ,如果能构造出 (ak=h\pmod p) ,那么 (a^{-1}=k\cdot h^{-1}\pmod p) ,所以需要让 (h) 较小。
掉线了……
Linear Matroid Parity
有很多对元素,一次要选一对,问最多选几对使得还是拟阵。
可以理解为:有很多行向量被分成一对一对,一次选一对,选最多使得线性无关。
普通拟阵是 NP-Hard 。
掉线,跑路。
可以做 colorful spanning tree 和别的一些神奇东西。
……#%¥……
删最少的点,使得剩下的图是森林。
NP-Hard 。
如果度数小于等于 3 那么是 P 。
先补成度数全部为 3 :……
掉线。