Petrozavodsk Camp2018 题解
Day 1: t.me/umnik_team Contest
A. Ciphertext
题意:有一套对01串的前缀编码系统。给出 $k (\leq 52) $ 个编码规则,每个长度不超过 \(52\)。显然,这些01串是不可能有前缀包含关系的。再给出一个长度为 $N (\leq 52 \times 10^6) $的字符串 \(S\)。现在要把 \(S\) 分解成尽量多的段,使得每段都不能被解码。
题解:首先我们考虑,单个的 \(0\) 和单个的 \(1\) 是否出现在编码规则里。显然只有可能存在某个才有意义(否则是答案是 \(N\) 或者 \(-1\))。不妨设存在 \(0\) 且不存在 \(1\)。
因为是prefix-free编码系统,有一个很显然的性质是:串 \(w\) 是否能被解码,等价于 \(0^k w\)能否被解码(之前放 \(k\) 个 \(0\))。
对于串 \(S\),假设我们固定了一段不能解码的后缀,考虑前面一段应该怎么划分。首先,由于\(0\) 能被解码,之前划分的每一段至少包含一个 \(1\),即最大划分数是 \(1\) 的个数。此外,我们也能构造出这个方案:对于每一个\(1\),把它和之前连续的 \(0\) 并在一起,独立成一段。
所以现在问题就是,找到最短的一段不能解码的后缀,然后答案再加上之前 \(1\) 的个数。为了快速找合法后缀,我们可以对编码倒着建立trie图,并拿 \(S\) 在图里跑一跑。一旦到了一个不是任何编码结束点的点即可停止。
B. Tree Hull
题意:给出一棵 \(N (3 \times 10^5)\) 个点的树。初始每一个点是白的。有 \(M\) 次操作,每次把一个点的颜色取反。每次操作后,问所有黑点构成的生成子树中的边权和。
题解:考虑转化。一条边在生成子树中,当且仅当它的两侧都有黑点。对于每条边,暴力维护它两侧的黑点数量,记为pair \((a,b)\)。
当一个点颜色发生变化时,它到根路径上的边的某一维会变化\(1\),其余边会在另一维变化 \(1\)。利用树链剖分,我们很容易把它们划成 \(log\) 段来维护。
现在考虑这么一个问题:要维护一些pair,每次把一段区间的某一维集体变化\(1\)(保证都是非负整数),或者全局询问所有两维都不为 \(0\) 的元素的权值和。直接维护很难,容斥一下,只要会统计某一维恰好等于 \(0\) 的权值和就好了。直接用线段树维护区间最小值以及它的个数即可。这样问题就解决可。
其实黑点会构成一棵类似虚树的东西,我们可以直接按 \(dfs\) 序来维护权值和。用经典的 set 操作来支持加和删。注意这题有点特殊,加入 \(dfs\) 序最小和最大的点时,贡献计算需要特判。
C. Tree Average Weight
题意:给出一个长度为 \(N (\leq 10^6)\) 数组 \(d_i\),表示一棵树的每个点的度数。\(d_i=-1\) 表示这个点的度数没有要求。在所有符合要求的树中等概率选择一种。定义一条边 \((u,v)\) 的代价是 \(size_u \times u+size_v \times v\),一棵树的代价是边的代价之和。求期望的总代价。
题解:推一下式子,其实我们只需求 \(\sum \limits_i (d_i-1) \cdot i\) 的期望。
方案是在所有合法形态的树里随机的,很自然地想到prufer序列。而 \((d_i -1) \cdot i\) 正好是prufer序列里的元素和。我们还有 \(-1\) 这几种标号没有填过,要填的个数也是确定的,那么期望和显然是取个平均值即可。
D. Intersection of Parabolas
题意:给出正整数 \(a\),求函数 \(y=(x-a)^2\) 和 \(x=(y-a)^2\) 围成的区域的面积。
题解:暴力积分后,答案是 \(4a-\frac{1}{3}\)。
E. Hamming
题意:给出一个长度为 \(N(\leq 8 \times 10^3)\) 的 \(01\) 串。对于每一个 \(k \in [1,N]\) 都要询问:所有长度为 \(k\) 的子序列,两两的海明距离之和。对\(40961\)取模,时限\(25\)s。
题解:转换求和思路,先枚举询问 \(k\),再枚举我们关注的位置 \(pos\),现在我们要快速知道:原序列中有多少左边长 \(pos-1\),右边长 \(k-pos\),且中间是\(0/1\) 的方案数,把它们乘一下加到答案里。这个东西无法快速算,那就尝试先全都预处理好。
可以用分治来解决这个问题。设 \(f_{l,r,x,y}\) 表示只考虑 \((l,r)\) 这一段,左边选了任意 \(x\) 个,右边选了任意 \(y\) 个,且中间是 \(1\) 的方案数。转移比较显然,比如先枚举 \(1\) 落在了 \((l,mid)\) 这个区间,所以就有 \(f_{l,r,x,y+z} \leftarrow f_{l,mid,x,y} \times C_{r-mid}^z\);另一侧也同理。这是一个很显然的卷积式子,可以用 \(NTT\) 加速。这样,一次分治的复杂度是 \(O(len^2 \log len)\)的。稍微推理一下可发现,所有区间加起来复杂度等效于 \(O(N^2 \log N)\)。
F. Knapsack
题意:有 \(N (\leq 60)\) 种物品,每种大小是 \(a_i\),且正好有两个。求拼出重量 \(W(4 \times 10^{18})\) 的方案数。其中 \(2 a_i \leq a_{i+1} \leq 10^{18}\)。
题解:状态数不会很多(证明留坑)。暴力 \(DP\) 即可。
G. Algebra on Segment
题意:给出 \(N (\leq 10^5)\) 个在模域 \(p (\leq 10^9)\)下的正整数,\(p\) 是一个质数。有 \(Q (\leq 10^5)\)个操作,每次给出 \((l,r,x) (x \geq 1)\),执行 \([l,r]\) 区间乘 \(x\);或者询问区间 \((l,r)\) 这些元素在模域 \(p\) 下的乘法的阶。
题解:先求出 \(p\) 的原根,把所有元素替换成原根的幂次,这样询问就变成了在模域 \(p-1\) 下的加法的阶了。
稍微推理一下,得询问的答案为 \(gcd(a_l,a_{l+1},\dots,a_r,p-1)\)。直接用线段树维护区间加区间gcd即可(要用到差分)。
这里我们要对 \(N+Q\) 个数求原根的幂次,这是复杂度瓶颈。BSGS的时候不要对 \(\sqrt P\) 分块,而要设 \(m=\sqrt {P \times (N+Q)}\)。如果使用hash(而且本题有点卡常,一定得用hash),复杂度就是 \(O(m)\) 的。
H. Continue the Sequence
题意:给出 \(N (N \leq 10^5)\) 个数 \(y_i\),分别表示某多项式在 \(x=i\) 时的点值。你要让这个多项式的度数尽可能小。现在问它在 \(x=N+1...N+M (M \leq 8 \times 10^5)\) 处的点值。
题解:本质是一个插值模型。如果采用拉格朗日插值,前缀积后缀积优化后,也只能 \(O(N)\) 求一次单点的值,太慢了。所以用牛顿插值,考虑差分。
做法①:对于 \(1\) ~ \(N\) 这 \(N\) 个数,我们暴力差分 \(N-1\) 次,最后得到一个数 \(d\)。那么显然,如果加上了 \(N+1 \dots N+M\) 这些数一起差分,到这一层也会全部变成 \(d\)。我们在后面添上\(M\)个 \(d\),再逆差分回去,就得到了答案数组。这个模拟是 \(O(NM)\) 的。
考虑加速这个过程。设一个多项式为 \(y_i \cdot x^i\)。注意到,每差分一次,就是把原多项式乘上一个 \((1-x)\) !因为 \((1-x)^{N-1}\)也可以快速计算得出,所以用一次 \(FFT\) 乘法,我们就能算出差分后的新多项式。它必然是从 \(x^N\) 开始有值,然后我们把大于 \(n\) 次的系数都抹掉,再把 \(N+1~N+M\) 这些幂次前面的系数改成 \(x^N\) 前的系数。那么怎么逆差分回去呢?那显然就是每次除 \((1-x)\) 呀。当然我们也能证明这件事,模拟差分过程,逆回去本质上是系数前缀和。而 \(\frac{1}{1-x}\)展开其实就是 \(1+x+x^2 \dots\)。那么我们只需把 \((1-x)^{N-1}\) 多项式求逆,乘上它即可得到答案系数。
做法②(标解):假设点值是 \(a_0\) ~ \(a_{n-1}\)。构造 \(n\)次多项式 \(f(x)=\sum \limits_{i=0}^{n-1} c_i \cdot x^{\lfloor i \rfloor}\)。显然我们可以通过暴力的方法,逐位确定 \(c_i\) 的值,因为有 \(c_k \cdot k!=a_k-\sum \limits_{i=0}^{k-1} c_i \cdot x^{\lfloor i \rfloor}\)。注意到下降幂可以化成两个阶乘想出,该式子是FFT形式。所以我们可以分治FFT,每次求完左边的 \(c_i\) 的时候,求出它们集体对右区间的贡献。这样我们可以在 \(O(N \log^2 N)\) 时间内求出 \(c_i\)。因为求后面的点值时多项式不变,我们可以类似地做一遍FFT,算出 \(c_0\) ~ \(c_{n-1}\) 对 \(c_{n}\) ~ \(c_{n+m-1}\) 的贡献。求出了后者后即可还原回 \(a_i\)。这一步是一个 log。
做法③:威威有更快的做法,懒得写了。
I. Partition Into Teams
题意:有 \(N (\leq 10^{18})\)个人,每个人可以投 \(A\) 或投 \(B\) 或弃权。问 \(A\) 票数多于 \(B\) 的概率。模质数 \(P (\leq 10^6)\)。
题解:转化为算平局的概率。很显然的做法是,求 \(\sum \limits_i C_{N,i} \times C_{N-i,i}\)。但这个不太可做。
从生成函数角度考虑。即我们要求 \((x^{-1}+x^0+x^1)^n\) 在 \(x^0\) 前面的系数。设 \(n=k \cdot P + r\),所以原式化为:
$ (x{-1}+x0+x1)r \times ((x{-1}+x0+x1)P)^k\(
<font color=red size=3>**由 freshman's rule,\)(x+y)P=xP+y^P$(高维也成立)**,所以转化为求 $ (x{-1}+x0+x1)r \times (x{-P}+x0+xP)k$ 在 \(x^0\)前面的系数。因为后者的幂次必然是 \(P\) 的倍数,前者也必须是。因为 \(r<P\),前者唯一的可能是取 \(x^0\) (才能最终拼出 \(x^0\))。而且因为 \(P\) 很小,前者 \(x^0\) 前的系数我们可以通过上述暴力求出。后者把内层的指数 \(P\) 改成 \(1\),和原问题等价,继续递归拆外层的指数 \(k\) 即可。
J. Determinant of a Graph
题意:给出一张 \(N (\leq 10^5)\) 个点,\(M (\leq N+50)\) 条边的连通无向图,求其邻接矩阵的行列式。
题解:有两个基本结论:删掉度数为 \(1\) 的点,行列式值不变;一条链删到只剩下 \(4\) 个点,行列式值不变。按照这样的方法重构这张图,得到不会超过 \(500\) 个点的新图,直接跑高斯消元即可。
Day 2: Ivan Kazmenko Contest 2
A. Circular Search
题意:交互题。有个人藏在\((0,0)\)~\((n,n)(n \leq 10000)\)正方形里的某个整点里。每次可以给出一个圆\((x,y,r)(\leq 10^9)\),会告诉你它在圆内还是圆外。最多问 \(50\) 次,要求找出这个人坐标。
题解:圆心在无限大出时,圆的边界可以看做是直线,则询问变成了半平面。分别对 \(x\)轴和\(y\)轴 二分即可。
C. Edit Program
题意:给出两个长度为 \(N(\leq 10^5)\) 的 \(01\) 串。问它们的编辑距离是否可以小于 \(N\)。若可以,打印一种方案。
题解:首先这两个串必须互为 \(01\) 翻转的串,否则通过修改来达到。注意到,子串里出现 \(010\) 时一定可以(去掉一个\(0\),加入一个 \(1\) 即可,可以少一步操作)。再把剩下的情况特判掉即可。
D. Faulty Keyboard
题意:给出《战争与和平》全集的txt文本。从中随机挑选出至少为 \(10^5\) 字节的连续的一段,并选择一个字母,在它每一个出现的地方有 \(50\)%的概率将其删除。给出操作后的文章段落,判断出少了哪个字母。
题解:直接统计每一种字符出现百分比是不行的(可能和部分字母集中出现在某处有关)。有一个很simple的想法:固定了一个字母后,考虑每一个包含它的单词 \(s\)。我们枚举这个单词对这个字母的所有删除方式,得到的不同的串叫做 \(s'\)。如果某个 \(s'\) 不是文中的单词,也不是其余单词删除后的结果,那么一见到它,我们就能确定出答案了。因为合法的 \(s'\) 很多,光做这些足以通过本题。我们只需对每一个字母筛选一些 \(s'\)(随机选择位置,确保有些能落在给定段落里)并打表进去。
F. Known Problem
题意:交互题。\(s_0\) 未知,定义 \(s_i=s_{i-1} \cdot 65539 \mod 2^{31}\),\(x_i=s_i \mod 10^6\)。考虑有 \(N(\leq 10^8)\)个数,每个数即为 \(x_i\)。你要求对它们求和。第 \(i\) 次询问时,你可以知道 \(x_i\) 的值。
题解:全部问完肯定会 TLE。注意到 \(s_i\) 的生成式可以用位运算加速,所以我们只需获知一个 \(s_i\),就可以暴力推出来求和了。
我开始采取了一个很复杂的方法来探寻 \(s\)。离线枚举每一个可能的 \(s\),暴力迭代直到有环,并推算出对应的 \(x\) 的数字环。设一个阈值 \(K=1000000\),对环上每连续 \(K\) 个数字进行哈希,结果为它开头的 \(s\) 的数值。对于被询问值每 \(K\) 个连续数字都哈希一下,看看是否能找到。期望询问 \(O(K)\) 个值即可。
其实这里产生 \(x_i\) 的模数很大。我们知道 \(x_1\) 后,\(s_1\)可能的值就只有 \(1000\) 种了。然后我们可以根据 \(x_2\) 继续缩小可能的 \(s\)。据称,最多问三次即可确定 \(s\) ……
G. K-th Bishop Covering
题意:有一个 \(N \times N (\leq 50)\)的棋盘,在其中放入 \(N\) 个象,使得所有格子都被(其或其攻击范围)覆盖。求字典序第 \(K\) 小的放置方法。
题解:神题……
H. Continue the Sequence
题意/题解:猜是哪种概率分布的题。直接算出每一种概率分布,比较哪种更像即可……
Day 3: MIPT Contest
B. Bag of Bags
题意:有 \(N(\leq 3 \times 10^5)\) 个物品,每个物品有实际大小 \(a_i\) 和容量 \(b_i\),\(a_i<b_i\)。若物品 \(i\) 和 \(j\) 满足 \(a_i<b_j\) 且 \(a_j<b_i\),则称它们是合适的。依次放入这些物品,某时如果产生了矛盾(存在三个物品 \(i,j,k\) 满足 \(i\) 和 \(j\),\(j\) 和 \(k\) 是合适的但是 \(i\) 和 \(k\) 不合适)则扔掉该物品。模拟这个过程。
题解:比赛时没看出来,这其实就是“线段模型”。将物品看做线段后,要求每一团可能相交的线段都要有公共的交。然后用set维护这一块一块线段集即可。
C. Circle Union
题意:给出 \(N(\leq 10^4)\) 个圆的半径,找一种摆放方案,使得它们有公共的交点,且面积并最大。
题解:威威带带我[可怜]。
D. Different Summands Counting
题意:给出 \(N(\leq 10^{18})\) 和 \(M(\leq 500)\)。对于 \(N\) 的每一个划分\(P\): \(N=a_1+a_2+\dots+a_M\)(不要求 \(a_i\) 升序),定义 \(f(P)\) 为 \(P\) 中不同的数字的出现次数。求所有划份方案的 \(f\) 值之和模一个大质数。
题解:设 \(F(x)\) 表示数字 \(X\) 的总收益,由容斥得 $F(x)=\sum \limits_{i=1}^{\min (M,\lfloor \frac{N}{X} \rfloor)} (-1)^{i+1} \cdot C_M^i \cdot C_{N-iX-1}^{M-i-1} $
外层还要对 \(X\) 求和,显然需要加速。因为 \(M\) 只有 \(500\),更换求和顺序可得 $ans=\sum \limits_{i=1}^M (-1)^{i+1} \cdot C_M^i \sum \limits_X C_{N-iX-1}^{M-i-1} $。把后面的组合数看做是关于 \(X\) 的 \(M-i-1\) 阶多项式,则它们的和是高一阶的多项式。直接插值即可。
E. Emerging Tree
题意:有一棵 \(N(\leq 10^6)\) 个点的有向树,方向是从根往叶子。现在要给每个点重新标号。按顺序加入 \(N-1\) 条边,要求任意一个时刻,每个点能走到的点的标号是连续的。打印任意一种方案或无解。
题解:(from lsmll)按照加边顺序倒着删边。边上维护P或者S标记表示前缀或者后缀。每次删边时向上找,直到到根或者要经过有标记的边。如果到根,如果根已经有P和S,则无解,否则加一条没有的标记。如果到一条路径中间,则无解,否则延伸这条路径的标记。注意已经删除的边之后就认为没有。如果有解,构造答案的话按照子树大小搞一下。
F. Fast Travel Coloring
题意:给 \(7 \times N\) 个点的无向完全图的边染色。颜色必须是 \([1,N]\) 的一种。染完后,要求对于任何两个点 \((u,v)\) 和任何一种颜色 \(c\),\(u \rightarrow v\) 只走颜色为 \(c\) 的边,最短距离不超过 \(2\)。
题解:考虑如何形式化地染色。颜色肯定有某种程度上的对称,所以我们将点分为 \(N\) 组(团),每组 \(7\) 个。每组代表一种颜色。
每组点之间的边好办,全连上自己组的颜色!那跨组呢?
对于颜色 \(i\) 组的点和颜色 \(j\) 组的点之间,没有理由连其它颜色的边。那到底是连 \(i\) 还是 \(j\) 呢?
回想我们要实现的要求:对于任何两个点 \((u,v)\)(不妨设 \(u\) 在颜色 \(i\) 组里,\(v\) 在颜色 \(j\) 组里)和颜色 \(c\),一定存在一个点 \(k\),使得 \(k\) 在颜色 \(c\) 的组里,且\((u,k)\) 和 \((v,k)\) 的颜色都是 \(k\)。且大胆猜测,每组颜色 \((i,j)\) 间 \(7 \times 7\)的边连法是一致的。
设 \(a_{x,y}=1\) 表示颜色 \(i\) 的第 \(x\) 个点和颜色 \(j\) 的第 \(y\) 个点之间连的是颜色 \(j\) 的边,否则是颜色 \(i\) 的边。
现在要尝试构造出一种合法的矩阵 \(a\) 满足要求。显然 \(a\) 是反对称的,且根据要求,对于任意两行 \((x,y)\) (\(x\) 和 \(y\) 意为点 \(u\) 和 \(v\) 所在组的位置,当然也可以相等),存在一个列 \(k\),使得 \(a_{x,k}=a_{y,k}=1\)。转化一下,即任意两行 \(and\) 值不为0。
我们可以通过爆搜+剪枝来搜出符合要求的矩阵。
G. Gnutella Chessmaster
题意:\(N \times N (\leq 10^5)\) 里放 \(k\) 个象且互不冲突,问方案数。\(k\) 从 \(1\) 到 \(2N-1\) 循环,把每个解模NTT质数输出。
题解:抱威威大腿。
H. Halve and Merge
题意:给出 \(N(\leq 2 \times 10^5)\) 个数的排列和 \(M\) 个操作。操作分为两种:①问位置 \(p\) 的数字是什么。②将区间 \([1,x]\) 和区间 \([x+1,N]\) 执行归并操作,得到的结果覆盖原排列。注意这里是单纯套用传统归并操作的做法,结果显然不一定有序。
题解:暴力模拟归并操作的具体过程,对于两个正在归并的数列 \(A\) 和 \(B\),不妨设 \(A_1<B_1\)。找到一个最大的 \(t\),使得 \(A_t<B_t\),然后将 \(A\) 的\([1,t]\) 放入结果数组,然后交替对 \(B,A\) 执行类似的操作。
我们期望,如果对剪切和移动每段(当然不能是每一个数)产生单位复杂度,总复杂度是科学的。
我们引进一种工具block来证明这件事。将初始的 \(N\) 个数划成一块块block,每一块block满足,块里所有数字都不大于块首(一旦出现,就分裂到下一个block去)。现在,我们得到了若干个block,且它们的首元素递增。
对于一次归并操作,它可能会划在一个block的内部。左侧依旧是完整的一块,但是右侧可能会分裂成很多小的block。考虑执行完归并操作后的结果:这些小的block会依照它们的首元素,有序地“插入”到左边的那些block里面。且归并的段数就是 \(O(新增小的block的个数)\)的。
自始至终,block的个数不会减少,最多为 \(N\) (此时该排列已经有序)。所以总操作段数就是 \(O(N)\) 的。
我们可以用非旋转treap很方便的维护序列的剪切和链接操作,总复杂度为 \(O((N+M) \log N)\)。
I. Interpolate
题意:有一个函数,系数、自变量和函数值都是 \(0\) 或者 \(1\)。自变量有 \(N(\leq 2000)\) 个,记为 \(x_1,\dots,x_N\)。系数有 \(2^N\) 个,记为 \(a_S\)。函数表达式为 $f(x_1,x_2,\dots,x_N)=\bigoplus \limits_{S=0}{2N-1} a_S \cdot \bigwedge \limits_{i \in S} x_i $。现在给出 \(M(\leq 2000)\) 组观测结果(保证自变量取值两两不同),构造一组系数使得符合要求。输出\(a_S\)取\(1\)的那些 \(S\)。
题解:表述复杂的傻逼题。对于一组 \(x_i\),设其集合为 \(U\),相当于把 \(a_S (S \subseteq U)\) 给异或起来。因为自变量取值两两不同,没有相同的 \(U\) 的观测。所以我们可以把观测结果按 \(U\) 中 \(1\) 的个数从小到大排序。每次决策一个观测结果时,先把把所有 \(a_S (S \subset U)\) 的异或起来,如果与结果相反,再设 \(a_U\) 为 \(1\) 即可。全程用bitset来加速。
J. Jaw-Dropping Set
题意:选择 \(1\) ~ \(N(\leq 10^9)\) 中尽量多的数使得任意两个数都没有整除关系。在这样的条件下,使得总和最小。有 \(T(\leq 10^5)\) 组询问,每次输出最大的和。
题解:最大个数显然是 \(\lfloor \frac{N+1}{2} \rfloor\) 个,只需取 $ \lfloor \frac{N+1}{2} \rfloor$ ~ \(N\) 即可。麻烦的是总和最小。
列出这样一张表:第 \(i\) 行列出所有仅包含 \(2^i\) 因子的数(比如第 \(0\) 行是奇数)。每列最多选一个数(且选最底下那个必然合法)。设\(f_i\)表示第 \(i\) 列最终选了啥。可以证明,\(f_i \geq f_{3i}+1\),且这个下界可以达到。
K. Kingdom Partition
题意&题解:最大生成树。
Day 4: Xi Lin Contest
A. Maximum Multiple
题意:多组询问。每次给出 \(N\) ,找到三个正整数 \((x,y,z)\) 使得 \(x|N,y|N,z|N,x+y+z=N\),且 \(xyz\) 最大。
题解:由均值不等式,\(N\) 是 \(3\) 的倍数时显然。当 \(N\) 是 \(4\) 的倍数但不是 \(3\) 的倍数时,能证明 \(\frac{N}{2},\frac{N}{4},\frac{N}{4}\)是最优解。打表发现其他不存在解。
B. Balanced Sequence
题意:给出 \(N(\leq 10^5)\) 个括号序列。以一定的顺序把它们接在一起,使得形成的括号序列合法子序列的长度最长。
题解:一道很old的题想了很久。显然每个序列先匹配一下,变成形如“)))……((("的形式。事实上,之后不存在一种排序的方案,使得最优解的一种是它们顺次接起来。考虑一个帅气转化:合法子序列的长度完全取决于前缀最小值的大小。
题目转化成,我们要让前缀最小值尽可能的大。首先将这些二元组分成两部分,"("多的和")"多的。显然,前者肯定总体都在后者前面。对于前者,每次经过前缀和都会增加,所以是按')'递增排;后者则相反。
C. Triangle Partition
题意:给出 \(3N\) 个点。每三个一组,使得构成的三角形没有交。
题解:标算给出的做法是:每次找凸包的一条边 \(AB\),再找一个与其夹角最小的点 \(C\),每次删除 \(ABC\) 即可。
实际上直接按横坐标排序,依次分组即可。
D. Distinct Valies
题意:有 \(N(\leq 10^5)\) 个位置,每个位置填正整数。给出 \(M(\leq 10^5)\) 个限制,要求 \([l,r]\) 这一段数字两两不同。求最小字典序方案。
题解:将互相包含的无效区间删掉,区间左右端点递增。遇到新的一段每次贪心地填最小的数字。弹出旧的一段就把那些数字都回收。这相当于是动态维护mex,线段树即可。
E. Maximum Weighted Matching
题意:初始时有一条边。有若干次操作:每次选择一条边 \(e=(x,y)\),复制一份,并在中间加入 $ k (k \geq 0)$ 个点(即连上 \((x,u_1),(u_1,u_2),\dots,(u_k,y)\) 这些边)。现在给出 \(N\) 个点,\(M\) 条边(\(N,M \leq 10^5\))的操作后的图(具体操作未知)。每条边会有一个边权,求此图的最大权匹配以及方案数。
题解:如果知道了图是怎么生成的,我们可以很方便的进行dp。设 $F_{E,u,v} $表示一段边 \(E\),“最左侧和最右侧的点是否在匹配里”的最大匹配以及方案数。链上一条一条dp过去,最后得到一些重边再merge一下。
考虑最后一次添的点,度数必然都是2。我们可以逆着来还原这个操作:每次找到一个度数为2的点,将其删掉,并在它连出去的两个点之间连上一条边。还原的同时还可以直接dp,直接在每一条边上记录\(2 \times 2\)的匹配信息。
有一个需要注意的地方:匹配信息是和这条边的起点/终点相关的。要给每条无向边定一个方向。
F. Period Sequence
题意:给出一个\(n=2000\)的正整数序列\(s_i (\leq 10^9)\)。定义 \(A_i=s_{i \mod n}+n \cdot \lfloor \frac{i}{n} \rfloor\)。对于一组\((l,r)\),定义\(f(l,r)=\sum \limits_x x \cdot cnt_x^2\),其中 \(x\) 是 \(A\) 中区间 \([l,r]\) 里所有出现过的数字,\(cnt_x\)是它们出现的次数。
现在给出 \(a,b (\leq 10^{18})\),求 \(\sum \limits_{a \leq l \leq r \leq b} f(l,r)\)。
题解:有一步重要的转化。\(f(l,r)=\sum \limits_{p=l}^r \sum \limits_{q=l}^r [A_p=A_q] \times A_p\)。
因为要对所有的\((l,r)\)求和,一个很显然的变换是:
\(\sum f(l,r)=\sum \limits_p \sum \limits_q [A_p=A_q] \times A_p \times (\min(p,q) - a+1) \times (b - \max(p,q) +1)\)。
注意到 \(p,q\) 会很大,而\(n \leq 2000\)。不妨设\(p=i+k_1 \times n,q=j+k_2 \times n\)。
我们的思路是,枚举 \(i\) 和 \(j\),计算对应的贡献。
列出\(A_p=A_q\)的要求,即\(s_i+k_1 \times n=s_j+k_2 \times n\)。即\(s_i-s_j\)必须是\(k_2-k_1\)的倍数。如果我们枚举 \(k_1\),那么 \(k_2\) 也就定了,不妨设其为 \(k_2=k_1+t\) 。由 \(a \leq p,q \leq b\),可以求出 \(k1\) 的下界 \(L\) 和上界 \(R\)。现在,我们再把 \(k_1\) 和 \(k_2\) 带入上述的求和式里,整理一下会得到 \(\sum f(l,r)=\sum \limits_{k=L}^R c_0+c_1 k+c_2 k^2+c_3 k^3\),\(c_i\)是常数。\(O(1)\)算一算即可。
G. Chiaki Sequence Revisited
题意:\(a_1=1,a_2=2,a_n=a_{n-a_{n-1}}+a_{n-1-a_{n-2}}\)。\(T(\leq 10^5)\) 组数据,求 \(\sum \limits_{i=1}^N a_i (N \leq 10^{18})\)。
题解:打表发现,每一个正整数都会在数列里出现,且数列是不降的。我们记 \(f_i\) 表示数字 \(i\) 出现的次数,会发现 \(f_i\) 即为 \(i\) 中含有的 \(2\) 的幂次加一。所以我们先二分第 \(N\) 个数是多少,每次判定数字 \(1\)~\(mid\) 一共会占用多少个格子。最终的和是一个等差数列。
H. RMQ Similar Sequence
题意:给出一个 \(N(\leq 10^6)\) 个数字的排列 \(A_i\)。现在要生成相同长度的数组 \(B_i\),每一个数是 \([0,1]\) 的随机实数。
设 \(f_p(l,r)\) 表示数组 \(p\) 中,区间 \([l,r]\) 里最大的数的下标。如果对于所有的 \((l,r)\),\(f_A(l,r)=f_B(l,r)\),则称 \(A\) 和 \(B\) 是 Similar 的。
如果 \(A\) 和 \(B\) 是 Similar 的,设收益为 \(\sum B_i\),否则收益为 \(0\)。求期望的收益和。
题解:比赛里用了帅气的积分做法。
先考虑一个简单的case:\(N\) 个独立变量 \(x_i\) 均在 \([0,1]\) 等概率随机,求最大值的期望。设 \(F_x\) 表示最大值 \(\leq x\) 的期望,显然 \(F_x=x^n\)。求导后得到概率密度函数 \(f_x=n \cdot x^{n-1}\)。那么最大值期望就是 \(\int_0^1 x \cdot f_x \,dx=\frac{n}{n+1}\)。
本题中,每次对 \(A\) 的最大值分治。这样,要求 \(B\) 的最大值也位于此,且两侧独立了。如果是Similar的收益是 \(1\),否则是 \(0\),那么期望收益就是 \(\prod \frac{1}{L}\),\(L\) 是每次分治区间的长度 (相当于强制最大值是某个位置)。
要计算 \(B_i\)的和的期望,考虑继续积分。枚举当前的最大值 \(x\),得到期望和为:\(\int_0^1 n \cdot x^{n-1} \times (g_L(x)+g_R(x)+x) \,dx\)。其中 \(g_L(x)\) 表示,如果左区间的每个数正好都随机在 \([0,x]\),期望和是多少。由期望的线性性,我们有理由相信,\(g_L(x)=x \times g_L(1)\),这样就能继续划成子问题递归下去了(每一段的问题都是:求解 \(g_{seg}(1)\))。
其实存在更 \(simple\) 的想法。如果只是要求 Similar 的概率,相当于是给 \(B\) 定义个大小关系的排列,使得满足树上的拓扑序要求。这个可以直接套一下定理算一下。而对于每一种合法的大小关系的排列,其期望和必然是 \(\frac{n}{2}\)!所以该问题就解决了……
Day 5: OpenCup Onsite, Warsaw U Contest
B. Product (8MiB ML!)
题意:给出 \(k (\leq 25)\) 个质数 \((p_i \leq 100)\) 和一个数 \(N (\leq 10^{18})\)。若只能用这些质数,能拼出的不超过 \(N\) 的最大的数是多少。
题解:看上去一副只能爆搜的样子。注意一些有效的剪枝,比如预处理 \(f_i\) 表示 \(\leq i\) 的数中的最大可行数。若当前乘积 \(cur\) 满足 \(\frac{N}{cur} \leq K\) 时停止搜索,直接乘上 \(f_{\lfloor \frac{N}{cur} \rfloor}\) 即可。
实际上可以meet in the middle。把质数尽量均匀地分成两组,每组直接搜出所有能拼成的数并排序(个数不会很多)。然后两个指针扫一扫即可。
注意到,这么做是会超内存的。
其实有个简单的trick能让meet in the middle的内存从 \(O(\sqrt N)\) 下降到 \(O(\sqrt[4] N)\)。
对于这两组质数,讨论哪一组对答案的贡献 \(\leq \sqrt {ans}\)。不妨设是第一组。先暴力搜第一组,同样把能拼成的数存在来并排序。第二组在搜索的时候,不用存数字了,直接在第一组的数组里二分找答案即可。
D. Machine Learning
题意:给出 \(N\) 个二维平面的点。用一条折线(只能折一次)去拟合它们,使得每个点 \(y_i\) 到折线上的 \(y\) 的平方和最小。
F. Permutation
题意:求第 \(K (\leq 10^{18})\) 小的长度为 \(N (\leq 250000)\) 的排列,满足逆序对数等于顺序对数。
题解:预处理 \(f_{i,j}\) 表示 \(1\) ~ \(i\) 的排列中,逆序对数量 \(=j\) 的方案数。打表发现 \(i > 100\) 时, \(j < 16\) 才有意义(否则值 \(> 10^{18}\))。
逐位确定,记录填到现在还剩多少逆序对 \(cur\)。暴力的做法时,从小到大枚举每一个没填过的数字 \(j\)。假设它是第 \(k\) 个被枚举到的,填了它的方案数就是 \(f_{n-i,cur-(k-1)}\)。和目前的 \(K\) 比较一下即可。
根据提过的性质,当 \(n-i>100\) 时,某时若 \(f_{n-i,cur-(k-1)}\) 有值,最多枚举 \(16\) 次必然能确定填的数。
有一个需要注意的地方是,最开始枚举的若干个数方案数可能均是 \(0\)(因为填了它后,后面的最大逆序对数量也达不到 \(cur-(k-1)\) 了)。所以要先设 \(k=max(1,cur-\frac{(n-i) \times (n-i-1)}{2}+1)\),从第 \(k\) 小的可以填的数开始暴力枚举即可。
找第 \(k\) 小的数可以用权值线段树,找下一个数可以用并查集,所以总复杂度是 \(O(N \log N+16N)\)。
G. Homework
题意:有 \(M\) 个长度为 \(N\) 的字符串。第一个串给定,之后每个串都是在前一个串的基础上,把第 \(x_i\) 个位置修改为 \(y_i\) 上形成的。将它们按字典序排序。
题解:直接建立可持久化线段树,在树上哈希即可。
I. Addition
题意:设计一个小程序,要求最多有 \(k(\leq 50)\) 行,每行两个字符串 \(a_i\),\(b_i (len \leq 8)\)。编译器会按照下图的逻辑执行。读入的 \(s (|s| \leq 100)\) 是任意的形如 \(x+y\)的字符串,\(x\) 和 \(y\) 是二进制数。要求输出的 \(s\) 是对 \(x\) 和 \(y\) 执行二进制加法后的结果。
题解:抱紧lsmll学长大腿。
Day 6: Ruyi Ji Contest
A. Rikka with Linker
题意:给出一个 \(N(\leq 18)\) 的有向图。要构造一个点的序列 \(s\),满足对于任何一条边 \((i,j)\),序列里最左边的 \(i\) 右边必须有一个 \(j\)。求最小长度。
题解:有点帅气的状压。倒着DP,设 \(f_S\) 表示末尾已经填过 \(S\) 这个数集,且 \(S\) 里这些数也已满足限制的最小长度。每次枚举往前填的数字 \(i\)。如果 \(i\) 的所有出点全在 \(S\) 里,用 \(f_S+1\) 去更新;否则用 \(f_S+2\) 去更新(意为目前已经产生环了,先填一个 \(i\) 去满足左侧数字的要求;等所有数字全填完后,在整个序列最开头再补一个 \(i\) 来满足 \(i\) 的限制)。
B. Rikka with Proper Fractions
题意:给出 \(\frac{c}{d}(c<d \leq N)\),求最简真分数 \(\frac{a}{b} (a<b \leq N,gcd(a,b)=1)\) 的个数,满足 \(\frac{a}{b} \leq \frac{c}{d}\)。
先不考虑互质,限制可以化为 \(ad \leq bc (b \leq N)\),即 \(f(N)=\sum \limits_{b=1}^N \lfloor \frac{bc}{d} \rfloor\)。
考虑互质的话,枚举 \(d=gcd(a,b)\),把 \(\mu(d) \times f(\lfloor \frac{N}{d} \rfloor)\) 加入答案即可。
现在考虑 \(f(N)\) 怎么求。
扩展成一般性的类欧几里得问题:求 $ \sum \limits_{i=0}^N \lfloor \frac{ai+b}{c} \rfloor $。
当 \(a \geq c\) 时,可以先把 \(\lfloor \frac{a}{c} \rfloor\) 移出来直接统计答案;\(b \geq c\) 时也类似。即:
\(f(a,b,c,N)=\frac{(N+1) \times N}{2} \times \lfloor \frac{a}{c} \rfloor+N \times \lfloor \frac{b}{c} \rfloor+f(a \mod c,b \mod c,c,N)\)
那么现在 \(a,b<c\) 了(这么讨论可以防止下面推导过程产生负数)。
设 \(M= \lfloor \frac{aN+b}{c} \rfloor\) (右端点值)。推导关键在于,将下取整变成求和式。
\(\sum \limits_{i=1}^N \lfloor \frac{ai+b}{c} \rfloor\)
\(=\sum \limits_{i=1}^N \sum \limits_{j=0}^{M-1} [\lfloor \frac{ai+b}{c} \rfloor \geq j+1]\)
\(=\sum \limits_{i=1}^N \sum \limits_{j=0}^{M-1} [ai \geq cj+c-b]\)
\(=\sum \limits_{i=1}^N \sum \limits_{j=0}^{M-1} i > \lfloor \frac{cj+c-b-1}{a} \rfloor\)
\(=\sum \limits_{j=0}^{M-1} (N- \lfloor \frac{cj+c-b-1}{a} \rfloor)\)
\(=NM-f(c,c-b-1,a,M-1)\)
观察第一维和第三维,可以发现,总复杂度和欧几里得一样。
C. Rikka with XOR
题意:给出 \(N,M(\leq 10^9)\),求 \(\prod_{i=0}^m (n \bigoplus i)\)。对一个大质数取模。
题解:对 \(M\) 进行数位DP。每次某位是 \(1\) 但决策放成 \(0\) 时,因为后面部分的异或值必然是 \(0\) ~ \(2^{n-i}-1\),所以要快速计算 \(\prod_{i=0}^{2^{n-i}-1} (x+i)\),\(x\) 是之前获得的异或和。这本质就是求两个阶乘。阶乘是经典的不可求问题(不考虑构造多项式的做法),分段打表即可。
E. Rikka with Equation
题意:给出 \(N(10^9)\),求合法三元组 \((a,b,m)(0 \leq a,b < m)\) 的个数,满足至少存在一组 \(x\) 和 \(y\),使得 \(x^2+y^2=a(\mod m)\) 且 \(xy=b(\mod m)\)。
题解:设 \(f(x)\) 为 \(m=x\) 时的个数。发现 \(f\) 是积性函数,所以我们只考虑 \(p^k\)。
当 \(p\) 是奇数时,转化为考虑三元组 \((a+2b,a-2b,m)\) (显然一一对应)。
在模意义下,方程必然有解,所以两者独立。我们只要保证它们存在二次剩余即可。
再转化为求 \(m\) 下二次剩余的个数,答案就是个数的平方。
从 这个博客 可能可以获得启发。个数为 \(\sum_{2i \leq k} \frac{\phi(p^{k-2i})}{2}\)。
题解说,\(p=2\) 时存在线性递推。(其实应该有很显然的规律)
F. Rikka with Lines
题意:给出一个矩阵\((x1,x2,y1,y2)(|x2| \leq 10^9,|y2| \leq 10^{18})\) 和 \(N(\leq 10^5)\) 条直线 \(a_i x+b_i(a_i \leq 10^9,b_i \leq 10^18)\)。求二元组 \((i,j)\) 对数,使得直线 \(i\) 和直线 \(j\) 有交,且交在矩阵里面或边界。
题解:剔除所有与矩阵没有交的直线。一般地,直线会与矩形有两个交点。如果 \(i\) 和 \(j\) 交在内部,则它们与矩阵的交点是交错的。所以这就变成了一个二维数点的问题。把交点离散化后,扫描线+树状数组即可。注意特判只有一个交点的直线。
此题卡精度,必须用分数类。获得新姿势:分数类不用记录正负号,只要把负号放在分子里,比较大小时直接分母乘一下比较即可。
G. Rikka with Bridges
题意:多组数据。对于一张无向图,称三元组 \((i,j,k)(i < j)\) 是 \(bridge\),当期仅当 \((i,k),(j,k)\) 有边,但 \((i,j)\) 无边。求点数为 \(N(\leq 1000)\),\(bridge\)个数不超过 \(K(\leq 8)\)的无向图个数。
题解:打表可以发现,如果一张 \(N\) 个点的连通图不是团,它至少有 \(N-2\) 个桥。
证明:归纳法。若一张连通图至少有一组桥 \((i,j,k)\),加入一个新点 \(t\) 后,桥的个数至少 \(+1\)。考虑和 \(t\) 连边的点 \(u\):要不 \(u\) 是中转点,要不 \(t\) 和所有点都有边,此时 \(t\) 是中转点(桥 \((i,j,t)\)形成)。
所以对于图中的每个连通块,如果点数 \(\geq 10\),必然是个团。那么我们可以先爆搜出 \(p(p \leq 10)\) 个点,\(q\) 个桥的连通图的个数。然后把整张图DP起来。
爆搜时注意用位运算来压掉一个 \(n\)。要跑好久。
J. Rikka with String
题意:给出一个长度为 \(N(\leq 10^5)\) 、字符集为 \(12\) 的字符串。对于每一个后缀都要询问:在字符所有双射的方案构成的 \(12!\) 种串中,是否存在一个串,使得它在这个串里是后缀最大的。
题解:考虑 \(N^2\) 暴力。询问 \(i\) 时,枚举后缀 \(j\),设 \(k=lcp(s_i,s_j)\),有个要求是:\(s_{i+k}>s_{j+k}\)。考虑一张 \(12\) 个点的拓扑图,那么我们从 \(s_{i+k}\) 向 \(s_{j+k}\) 连一条边,意为前者要大于后者。最后得到的图如果没有环,必然有一种拓扑序列,就必然有解。
现在的问题是,如何得到每一个后缀的图。考虑建立后缀树,一个后缀的所有限制,产生在它到根路径上的所有分叉上。所以从根开始DFS,维护一张图表示从根到目前的点 \(x\) 获得的限制。可以用位运算加速,这样只需维护 \(12\) 个数。不过最后找环是 \(12^2\) 的,所以复杂度就是 \(O(144N)\)。
Day 7: Izhevsk STU + Ufa SATU Contest
A.Equal Digits
题意:给出一个长度为 \(N(\leq 10^5)\) 的数字串。现在要选择一些不相交的区间把它们删去,使得剩下的串每种数字最多出现一次。每个选择区间的长度必须大于 \(1\),且必须首字符和尾字符相等。只要删除位置的集合不同,就算不同的方案。求方案数模大质数后的值。
题解:设 \(f_{i,S}\) 表示考虑前 \(i\) 位,剩下的数字集合是 \(S\) 的方案数。转移的话,要不留下这个数,从 \(i-1\) 处转移;要不删除这个数,枚举一个 $j<i,从 \(f_{j,?}\)里转移过来。注意要求 \(a_i=a_j\),所以可以对数字建立一个辅助DP,就不需要每次枚举 \(j\) 了。
B.Remove the Tree
题意:给出一棵 \(N\) 个点的树。每次可以选择两个连通的点 \(u\) 和 \(v\),把它们路径上的边都删掉。求最小的删的次数,使得所有边都被删掉。
题解:考虑直接 DP。设 \(f_i\) 表示到点 \(i\) 子树内部分配完删边方案的最小值,\(g_i\) 表示还有向上的一条链的最小值,转移即可。
D.Road Connectivity
题意:给出一张 \(N(\leq 5)\) 个点的无向图,表示时刻 \(T=0\) 的连通信息。每过一单位时间,随机一条边,将其存在性翻转。有 \(1000\) 组询问,每次给出 \((L,R) (L \leq R \leq 10^{18})\),询问 \(L\)~\(R\) 中至少有一个时刻图是连通的概率。答案对大质数取模。
题解:容斥后是求全不连通的概率。做法分为两个步骤:求出到时刻 \(L\) 时不连通的概率;求出从时刻 \(L\) ~ \(R\) 一直不连通的概率。
设 \(M=\frac{N \times (N-11)}{2}=10\),所以边集状态是 \(S=2^{10}=1000\)。打表发现,其中不连通图个数 \(K=296\) 种。
对于第一问,直接矩乘复杂度是 \(O(S^3 \log R+Q \times S^2 \log R)\),显然会 \(TLE\)。其实我们可以直接枚举 \(L\) 时刻的一种不连通的状态 \(U\),强行算它出现的概率。对于这 \(M\) 条边,有些边存在性和 \(T=0\) 时相同,有些相反。我们可以设 \(f_{i,j}\) 表示:到时刻 \(i\),有 \(j\) 条边存在性和初始图不同的概率。因为 \(j \leq 10\),直接对 \(i\) 矩乘即可。那么对于这种边集状态 \(U\),若有 \(e\) 条边和初始时相反,它出现的概率就是 \(f_{L,e} \times C_{M,e}\)。这样,第一步我们在 \(O(10^3 \log R+ Q(10^2 \log R+K))\) 时间内解决。
对于第二问就不能这么优化了,因为我们要保证中途经历的图都是 \(K\) 种之一的。此时考虑压缩矩阵的大小。虽然不连通的有 \(K\) 种,但是本质不同的只有 \(13\) 种。所以就把矩阵大小压成 \(13\) 了。这一步复杂度是 \(O(13^3 \log R+Q \cdot 13^2 \log R)\)。
E. Binary String
题意:有一个长度为 \(N(\leq 1000)\) 的 \(01\) 串未知,要交互探知。每次可以询问 \((L,R)\),有50%的概率返回 \(L\)~\(R\) 之间的 \(1\) 的个数;还有50%的概率等概率返回 \([0,R-L+1]\) 中非正确答案的数值。同样的区间最多只能问一次。要在 \(60000\) 步之内获得该串。
题解:考虑 \(501\)~\(1000\) 怎么确定,反之亦然。我们的目的是,严格确定出 \(sum_{1-500},sum_{1-501},sum_{1-502},\dots\) 这些区间的和,这样答案也就出来了。首先是 \(sum_{1,500}\)。做法很简单,我们不仅可以问 \((1,500)\),还可以问 \((1,x)\) 和 \((x+1,500)\),把两者加起来即可。问足够多次后,找到出现次数最多的数字,其必然就是 \(sum_{1,500}\) 。往后考虑 \(sum\) 时,就不必刺探这么多次了,因为 \(sum_{1,i-1} \leq sum_{1,i} \leq sum_{1,i-1}+1\),所有不在这个区间里的值必然是错的,直接无视。
G. Token and Dice
题意:你想从 \((x,y)(|x|,|y| \leq 10^9\) 走到 \((0,0)\),每次只能走整数坐标。初始时你有一颗六面都是 \(1\) 的骰子。每轮,交互器先给你一个新骰子(六面都是 \(1\)~\(10000\)的随机数),你可以选择是收下或者扔掉;然后交互器会把你的所有骰子都丢一遍,把朝上的数字之和 \(s\) 给你。之后你必须从原来的位置 \((x_0,y_0)\) 走到新的位置 \((x_1,y_1)\),满足 \(\lfloor \sqrt {(x_0-x_1)^2+(y_0-y_1)^2} \rfloor=s\) 或 \(\lceil \sqrt {(x_0-x_1)^2+(y_0-y_1)^2} \rceil=s\)。要求在 \(60000\) 轮内走到 \((0,0)\)。
题解:发现 \(s\) 是不可控的,所以保留的骰子数量 \(K\) 一定很少,这样所有可能的 \(s\) 我们都能掌握。
大致想法是这样的:设 \(R\) 是可能的最大的 \(s\)。以原点为圆心画一个半径为 \(R\) 的圆。当离 \((0,0)\) 远的时候,直接往原点方向走即可;而一旦走到了圆上,无论下一步 \(s\) 是什么,我们都要keep在圆上(因为 \(R\) 是最大的 \(s\) ,任何 \(s\) 都能找到一条合法的弦走过去)。这样,只要某次掷出 \(R\),我们就能走回 \((0,0)\) 了。
细节还是挺多的。走到原点附近的期望步数是 \(\frac{10^9 \cdot \sqrt 2}{6sum_i}\),所以骰子的数字和要尽可能的大;最后掷出 \(R\) 的概率是 \(\frac{1}{6^K}\),所以骰子个数要尽可能的小。为此,我设了参数 \(K=4\) (期望几千步就能取到 \(R\))。然后为了使和尽量大,先扔 \(5000\) 次骰子,把每次 \(sum \geq 47500\) 的骰子保留(实测大概会有 \(10+\) 个,所以保留 \(4\) 个绰绰有余)。这样基本不会超过步数限制。
还有一个很头疼的问题是,必须要整数坐标。比如在圆上绕圈圈时,找到符合要求的整点很头疼。每次我是先拿 \((0,0,R+0.5)\) 和 \((x,y,s)\) 做一遍圆交,交点 \(p\) 默认是最优参考点。然后我把 \(p\) 附近的一块矩阵拿出来,把其中的整点都纳为考虑对象。最优的点是 \((R-1)^2 < x^2+y^2 < (R+1)^2\) (能一步到原点),如果没有,我们就取尽量靠近这个范围的点即可。
Day 8: Grand Prix of Zhejiang, Yuhao Du Contest 5
B.Border
题意:给出一个长度为 \(N(\leq 10^6)\) 的 \(01\) 串 \(S\)。对于一个区间 \((l,r)\),定义 \(f_{i,j}=max(k | 0 \leq k \leq j-i,S[i..i+k-1]=S[j-k+1..j])\)。
要求所有 \(f(l,r)\) 的和。读入 \(seed\),\(S\) 是按以下方式生成的。
题解:由于数据是随机生成的,可以认为,最大的答案 \(K \leq 45\)。枚举起点 \(i\),反着统计:对于一个串 \([i,i+k-1]\),统计它会对哪些 \(j\) 产生贡献。假设我们简单地统计一下 \([i..n]\) 中该串的出现次数,设为 \(f_k\)。注意这个 \(f_k\) 不是真正 \(k\) 的贡献,因为可能会重复统计。对于两个串 \([i,i+k1-1],[i,i+k2-1](k1<k2)\),如果前者是后者的子串,前者就会重复统计。所以我们可以再倒着枚举 \(k\),\(g_k=f_k-\sum \limits_{j=k+1}^K [S_k \in S_j] \cdot g_j\)。
对于求 \(f_k\),我们可以倒着枚举 \(i\),倒着往后缀自动机里添加点。询问时,从 \(K\) 开始倒着循环,实时维护目前区间所在的点,每次弹出当前区间的第一个位置的字符。计算 \(g_k\) 时可以用 kmp 来计算。总复杂度是 \(O(N(K+k^2)\),\(K\) 是最大可能答案,\(k(\approx 17)\) 是不同的 \(i\) 的平均最大答案。
C.Convolution
题意:给出两个长度为 \(N(\leq 2 \cdot 10^5)\)的数组 \(a\) 和 \(b\),设 \(c_k=\sum \limits_{i=0}^k \binom{k}{i} a_ib_{k-i} \mod 2^{32}\)。输出 \(c\) 数组。
题解:简单化一化,设 \(A_i=\frac{a_i}{i!}\),对 \(A\) 和 \(B\) 作卷积。但是 \(i!\) 里包含 \(2\) 的幂次,不能简单地求逆元。
显然要把 \(2\) 的因子分开。经典结论: \(k!\) 里 \(2\) 的因子正好有 \(k-bit(k)\) 个。
设 \(p_i\) 是 \(i!\) 里除掉所有 \(2\) 的因子后的结果。所以 \(c_k=k! \sum \limits_{i=0}^k \frac{a_i}{i!} \frac{b_{k-i}}{(k-i)!}=\frac{p_k}{2^{bit(k)}} \sum \limits_{i=0}^k \frac{a_i \cdot 2^{bit(i)}}{p_i} \frac{b_{k-i} \cdot 2^{bit(k-i)}}{p_{k-i}}\)。
我们可以把 \(A_i\) 看成两个数值 \(\frac{a_i}{p_i}\) 和 \(bit(i)\) 的合成。对其做(权值分段的) \(FFT\) 即可,随后把答案除掉 \(2^{bit(k)}\) 即可。数值会达到 \(2^{32} \cdot 2^{17} \cdot 200000\),为防止超过 \(LL\),可以对 \(2^{50}\) 取模。
L.Link Cut Digraph
题意:有一张 \(N(\leq 10^5)\) 个点和 \(M(\leq 2.5 \times 10^5)\) 的有向图。依次往图里加边,每加一条,询问目前图中有多少点对 \((u,v)\),满足 \((u,v)\) 可以互相到达。
题解:本质上就是要实时维护强连通分量。但是这是论文题,不可做。
其实有一个精妙的整体二分做法。设 \(solve(l,r,E)\) 表示正在做时间轴上的 \((l,r)\) 区间,目前等效边集是 \(E\)。设 \(mid=\frac{l+r}{2}\),先把 \(E\) 中所有出现时间 \(\leq mid\) 的边拎出来,跑一遍 tarjan。然后思考:对于一条在强连通分量里的边,它对于 \([mid+1,r]\) 是无效的(我们只需把这些点缩起来好了);同理,对于一条不在SCC里的边,它对 \([l,mid]\) 是无效的(因为加入了 \([l,mid]\) 所有边,都没有形成环,删了一些边后肯定也没有)。所以 \(E\) 可以划成两个不交的集合。这样复杂度就变成了 \(O(M \log N)\)。
Day 9: Mixed Contest
B.Bingo
题意:给出 \(N \times M(N,M \leq 110)\) 的格子图。要在里面选出 \(M\) 个格子,每列正好选一个。要求选的最多的行和选的最少的行的差尽量小。满足这个条件下,使选取的格子上的数字的最大值尽量小。
题解:判一下即可确定最小的差是多少。然后二分一下跑上下界网络流即可。
C. Communication Between Robots
题意:有 \(200\) 组数据。给出 \(N(\leq 16)\) 个二维坐标的点,起点位置为 \((x0_i,y0_i) (|x| \leq 10^6)\),单位时间的速度向量是 \((vx_i,vy_i)(|v| \leq 1000)\)。问 \(0\)~\(T(\leq 1000)\) 时间里,这些点之间的最小生成树最小是多少。
题解:类似一道TC经典题。任意两点间的距离形如 \(\sqrt{At^2+Bt+C}\)。两两枚举这 \(N^2\) 个距离,求出它们的交点 \(t\) 并设为关键点。容易发现,当 \(t\) 处于关键点之间的一段时,边的大小关系是确定的,所以最小生成树上的边也是确定的。我们只需对这些函数的和在 \([t_i,t_{i+1}]\) 中求个最小值。
凸函数之和仍然是凸函数。
D. Doublindromes
题意:称一个串 \(s\) 是 \(doublindrome\) 的,当且仅当它是个回文串,且它可以拆成两个非空回文串 \(a\) 和 \(b\) 的和。给出一个长度为 \(N(\leq 10000)\) 的串,求它所有长度 \(\geq k\) 的 本质不同的 \(doublindrome\) 的子串的个数。
题解:本质不同的回文串个数是 \(O(N)\) 的,所以我们可以用 \(manacher\) 暴力找到所有回文串。如何判它是 \(doublindrome\) 的呢?猜测它一定有一个循环节,即 \(s=xx \dots x\)。所以直接对其跑一遍 \(kmp\) 即可。
F. Form the Maximal Set
题意:一个圆的圆周上均匀刻着 \(1\) ~ \(N(\leq 8000)\) 这 \(N\) 个数字。给出 \(\frac{N}{2}\) 条线段,分别连接两个不同的点。找到尽可能多的线段集合,使得它们两两都有交。求最大集合的大小。
题解:先固定一条线段 \(l_0\)。假设先有一条线段 \(l_1\) 与其有交。接下来与它们都有交的直线 \(l_2\) 两侧的端点满足一定的单调性。如果我们把 \(l_0\) 一侧的点的重新标号为 \(1,2,\dots\),另一侧必须取出一个逆序的序列才能符合要求。所以此题就转化成了 \(LIS\)。
H. Hokusai Artworks
题意:给出一张 \(N\) 个点 \(M(\leq 10^5)\) 条边的有向图,每个点有个点权。从 \(1\) 出发,每奇数次到的点都能获得它的点权(可以重复经过点,但不能重复获得点权),可以在任意点结束。问最大收益。
题解:首先先缩环成点,一定是按照拓扑序走过去的。对于一个SCC,如果它至少存在一个奇环,所有点都能取到;否则要奇偶染色,只能取某种奇偶性的点权。不妨设 \(come_{x,0/1}\) 表示从之前的SCC在奇数/偶数步进入点 \(x\) 时,之前能获得的最大收益。设 \(go_{x,0/1}\) 表示环里走完后,在奇数/偶数步从 \(x\) 出去的最大收益。根据是否有奇环分情况转移即可。