IOI2020国家集训队作业 Part 1

开坑!开坑!开坑!虐身虐心警告。

CF504E Misha and LCP on Tree

  • 给定一棵树,每个节点有一个小写字母。
  • \(m\) 次询问,求路径 \((a,b)\)\((c,d)\) 的 LCP。
  • \(n\leq 3\times 10^5,m\leq 10^6\)

直接 Hash,不要傻傻的写成两只 \(\log\),更不要直接套个二分 + 树剖三只 \(\log\)

直接套用树剖结构,提取出 $\log $ 个区间,先区间相消,如果消不了了就在区间里二分,小常数单 \(\log\)

CF505E Mr. Kitayuta vs. Bamboos

  • 给定 \(n\) 个数 \(h_i\),进行 \(m\) 轮操作,每次可以选择 \(k\)\(h_i\) 进行 \(h_i\gets \max(h_i-p,0)\)
  • 每轮操作后,会有 \(h_i\gets h_i+a_i\)
  • 最小化最终的 \(\max h_i\)
  • \(n\leq 10^5,m\leq 5\times 10^3,k\leq 10\)

二分答案改为每次给 \(k\) 个数加,逆向看是否能倒回 \(m\) 轮。

不要分步模拟这个过程,因为加减均有交换律,所以当直接枚举轮数,每次给“最紧急”的 \(k\) 个加,直接用堆维护。

如果中途都没了那就没了,否则最后还要让每个数能达到初始值。

CF506E Mr. Kitayuta's Gift

  • 给定字符串 \(s\),求在 \(s\) 中插入恰好 \(n\) 个小写字符使其变为回文串的方案数。
  • \(|s|\leq 200,n\leq 10^9\)

老神仙了。

第一步是要想到一个关于 \(m=|s|\) 的多项式的算法,也算是关键步骤了。

因为是回文串,所以两端应当一起考虑,先假设 \(n+m\) 为偶数。

\(f(i,l,r)\) 表示填了首尾 \(i\) 对字符,前后尽量和原串匹配后,还剩下区间 \([l,r]\) 的方案数。

\(g(i)\) 表示用 \(i\) 对首尾能完全匹配的方案数,答案就是 \(g(\frac{n+m}{2})\)

转移需要讨论一下:

  • \(s_l=s_r\)
    • \(r-l\leq 1\)\(g(i+1)\gets f(i,l,r)\)\(f(i+1,l,r)\gets 25\times f(i,l,r)\)
    • \(r-l>1\)\(f(i+1,l+1,r-1)\gets f(i,l,r)\)\(f(i+1,l,r)\gets 25\times f(i,l,r)\)
  • \(s_l\neq s_r\)
    • \(f(i+1,l+1,r)\gets f(i,l,r)\)
    • \(f(i+1,l,r-1)\gets f(i,l,r)\)
    • \(f(i+1,l,r)\gets 24\times f(i,l,r)\)
  • \(g\)\(g(i+1)\gets 26\times g(i)\)

为了去除 \(n\) 的影响,可以强行用矩阵加速这个 \(O(m^2)\) 个状态的递推,复杂度为 \(O(m^6\log n)\)

发现这类转移能很好的表达到一张图上(来自官方题解):

这是 \(\texttt{abaac}\) 的转移过程,红色和绿色分别对应 \(s_l\neq s_r\)\(s_l=s_r\) 两种转移。

观察到上述转移中,红色点有 \(24\) 的自环,绿色有 \(25\),蓝色对应的 \(g\) 则有全图唯一的 \(26\) 的自环。

同时不难发现,非自环边的权值都是 \(1\),并且只能从绿色点到达目标点。

最终答案等价于从右上角出发,经过恰好 \((n+m)/2\) 步到达目标点的路径权值之和,路径权值是途径权值的乘积。

将图片可视化之后,很快能发现,路径的具体形态不被关心,而是只关心路径上红色点(\(24\) 的自环)和绿色点(\(25\) 的自环)的个数。

而且能够发现,若一条路径有 \(x\) 个红色点,就一定有 \(\lceil\dfrac{m-x}{2}\rceil\) 个绿色点。

因为红色点的出边每次将区间长度 \(-1\),而绿色则大部分情况下 \(-2\),只在转移到终点时有特殊,所以要上取整。

综上,所有红色点个数相同的路径是本质相同的,可以利用这一点加速转移!

分别建立如上面第一张图的转移路径,每张只有 \(O(m)\) 个点,而本质不同的路径也只有 \(O(m)\) 个,直接矩阵转移就是 \(O(m^4\log n)\) 的。

当然要记搜预处理出 \(f(i)\) 表示途径恰好 \(i\) 个红色点的转移路径数。

同时实际上发现这样做还是太傻了,可以直接上面一排红色点,下面一排绿色点,再在两排之间对应连边就好了,如上面的第二张图。

复杂度变为 \(O(m^3\log n)\),而且转移形式是 DAG,所以转移矩阵是上三角矩阵,所以可以减少很多常数。

对于 \(n+m\) 为奇数的情况,把它当作 \(n+m+1\) 处理,再容斥掉一些情况即可。

需要容斥掉最后一次匹配不能填上当个字符的方案,发现就是只转移 \(r-l=1,g(i+1)\gets f(i,l,r)\) 且最终 \(g\) 没有多余匹配的方案。

无非就是把 \(f\) 重新计算,再把终点的自环去掉,再跑一遍即可。

CF512D Fox And Travelling

  • 给定 \(n\) 个点 \(m\) 条边的无向图,一个点只有当它度数 \(\leq 1\) 时才能被删除。
  • 对于每个 \(k\in[0,n]\),求有序删除 \(k\) 个节点的方案数。
  • \(n\leq 100,m\leq \dfrac{n(n-1)}{2}\)

发现对于一个环它永远无法被选择,需要考虑的只有有根树和无根树两种情况。

均可类似的使用树形 DP 解决,对于有根树的计算需要去重,钦定/换根/直接除法 都是不错的选择。

CF516D Drazil and Morning Exercise

  • 给定一棵带边权的树,定义 \(f_x=\max_{i=1}^n \text{dis}(x,i)\)
  • \(q\) 次询问最大的满足 \(\max _{x\in s} f_x-\min _{x\in s} f_x\leq l\) 的连通块 \(s\) 的大小。
  • \(n\leq 10^5,q\leq 50\)

把直径提取处理画成一排,把子树挂在上面,十分形象。

发现每棵子树的 \(f\) 值都是随深度严格递增的,这一点非常有用。

根据连通块是否跨子树讨论,只在一个子树内非常好统计。否则考虑枚举连通块中的 \(\min\),它一定是某棵子树的根

然后处理出这个根能扩展到的区间,因为递增性保证连通性,所以相当于二位数点,离线树状数组即可。

实际上 std 更简单,考虑双指针滑动一下,从大到小就不会影响连通性了,只是单点取消的时候在对应连通块 \(-1\)

CF516E Drazil and His Happy Friends

  • 有标号为 \([0,n)\)\(n\) 个黑点和标号为 \([0,m)\)\(m\) 个白点。
  • 初始有 \(B\) 个黑点和 \(G\) 个白点是快乐的,其他都是不快乐的。
  • 在第 \(i\) 天,编号为 \(i\bmod n\) 的黑点会和 \(j\bmod m\) 的白点联会,如果有任意一个快乐,那么联会后两者都会快乐。
  • 求至少多少天能使所有人快乐,或者判定不可能。
  • \(n,m\leq 10^9,B,G\leq 10^5\)

妙妙数论题。

只想到了只有 \((n,m)|\text{dis}\) 的点对会在某个时刻联会。

实际上考虑直接按 \(\bmod d\) 分类,分别考虑答案,对于 \(\bmod d=i\) 的类,最终的实际贡献是 \(d\times \text{ans}+i\)

对于一类,如果初始没有开心的人就无解,否则一定有解。注意若 \(d>B+G\) 就一定无解,看似没用但实际保证了 \(d\)\(10^5\) 级别的。

不妨设 \(n>m\),首先特判掉在前 \(m\) 步就完成的情况。

否则只需要考虑左边 \(n\) 个点的开心时间,因为这样倒退 \(m\) 步,要么感染右边,要么被右边感染。

把右边初始开心的都对称到左边来,发现若左边 \(i\) 初始开心,他就会先感染右边的 \(i\),并借此感染到左边的 \((i+m)\bmod n\)

那是否能视为**左边的 \(i\) 能感染左边的 \((i+m)\bmod n\) **呢!

发现可以建图:

  • 对于初始开心的点 \(i\),连边 \((s,i,i)\)
  • 对于任意点 \(i\),连边 \((i,(i+m)\bmod n,m)\)

跑最短路,最大值就是答案,可惜总点数过大,不能接受。

但是不难发现,第二种边将图连成了一个大环,而如果 \(i\)\((i+m)\bmod n\) 这两个相邻节点初始均不开心,那么后者一定被前者感染。

换句话说前者就是不重要的,只需要保留初始开心的点,和它们在环上的前驱即可,这是 \(O(B)\) 个的,就有保证了。

连边的时候有些技巧,就是对每个初始开心的点都建两个点,\(a_i\) 表示自己,\(b_i\) 表示自己的前驱。

然后连边 \((s,a_i,i),(b_i,a_i,m)\),同时还需要找每个点在环上的相邻点,设 \(x\) 表示最小的满足 \(mx\equiv 1\pmod n\) 的值(可以用一次 exgcd 求出)。

那么两个点 \(c,d(c>d)\) 的环上距离就是 \((d-c)\times x\bmod n\),固定一个起始点,求每个点到它的距离,排序就能得到在环上的相对顺序了。

注意是从 \(a_i\to b_j\) 连边,对于的距离要 \(-1\),同时还要判断一下是否有 \(a_i=b_j\) 的情况,如果有就令两点连双向 \(0\) 边使之完全等价。

CF521D Shop

  • 给定 \(k\) 个正整数 \(a_i\)\(n\) 个操作 \((t,i,b)\),操作分为 \(3\) 种:
    • \(t=1\),操作是 \(a_i\gets b\)
    • \(t=2\),操作是 \(a_i\gets a_i+b\)
    • \(t=3\),操作是 \(a_i\gets a_i\times b\)
  • 可以选择操作中至多 \(m\) 个,并按照一定顺序执行,求最大可能的 \(\prod a_i\)
  • \(n,k\leq 10^5,m\leq n\)

降智罚坐,被 IV 痛骂。

\(1\) 操作转 \(2\) 操作是简单的,\(2\) 操作转 \(3\) 实际也不难,就是将 \(s\gets s+a\) 变为 \(s\times \dfrac{s+a}{s}\)。用一个堆贪心就行了。

CF521E Cycling City

  • 给定一张无向简单图,问图中是否能找到两个点,使得两点之间有至少 \(3\) 条除端点外不交的简单路径。
  • \(n,m\leq 2\times 10^5\)

降智罚坐,被 IV 痛骂 \(\times 2\)

一直往点双想,实际上后来看到题解区有个结论:当且仅当一个点双恰为一个环时无解,否则一定可以构造解。

但是讨论巨大多。

实际上,一个更简洁而本质的结论为:若存在两个相交的环时一定有解,否则一定无解。充要都显然。

那么直接跑个 dfs 生成树,对返祖边差分覆盖,找到一个被覆盖 \(\geq 2\) 次的树边就直接构造即可。

CF526F Pudding Monsters

  • 给定 \(n\times n\) 的棋盘,共有 \(n\) 个棋子,且每行每列恰好一个。
  • 求有多少 \(k\times k\) 的子矩形中恰好有 \(k\) 个棋子。
  • \(n\leq 3\times 10^5\)

这个是真的简单,不难发现 \(k\times k\) 中的极大情况就是有 \(k\) 个,很直觉的就变成 \(\max -\min=r-l\) 了。直接分治。

CF526G Spiders Evil Plan

  • 给定一棵带边权的无根树,\(q\) 次询问,每次给定 \(x,y\)
  • 要求选择 \(y\) 条树上路径(可交)构成一个包含 \(x\) 的连通块,且最大化连通块的边权和。
  • \(n,q\leq 10^5\),强制在线。

发现一个有 \(\leq 2y\) 个度数为 \(1\) 的点(叶子)的连通块(子树)能够被 \(\leq y\) 条路径覆盖。

然后选择 \(2y\) 个叶子到根的路径就是经典长剖 + 贪心,但是以每个点为根不能接受。

实际上,观察到最大的路径一定是该点到直径两端中的某个点,所以只用这两个点为根预处理。

注意直径端点一定是叶子,所以只有 \(2y-1\) 可以用,唯一问题是如果前 \(2y-1\) 条链不包含 \(x\) 怎么办。

再上贪心,无非两种情况:

  • 去掉最后一条链换成 \(x\) 所在长链从底到上。
  • 去掉 \(x\) 往上跳第一个到达的被选路径的一段,并改接为 \(x\) 所在的这段路经。

倍增预处理一下即可。

CF527E Data Center Drama

  • 给定连通无向图,加尽量少的边,然后给边定向使得每个点的出入度都是偶数。
  • 要求输出方案,可以有自环 / 重边。
  • \(n\leq 10^5,m\leq 2\times 10^5\)

比较刻意的构造,必要性探路。

每个点出入度都是偶数的必要条件是:作为无向图的时候,每个点的度数为偶数。

而这是无向图有欧拉回路的充要条件。

所以先将奇点配对连边,然后如果总边数为奇数再连一个自环,然后跑欧拉回路的同时,交替正负定向即可。

CF536D Tavas in Kansas

  • 给定一张无向图,点有点权(可正负),边有边权。A 和 B 有各自的起点,两人博弈。
  • A 先手,每次需要选择一个 \(d\geq 0\),将距离 A \(\leq d\) 的点都计入当前选手。
  • 一个点不能被计入多次,如果全图的点均被计算了,那么游戏结束,得分高者获胜。
  • \(n\leq 2\times 10^3,m\leq 10^5,|p_i|\leq 10^9\)

简单 DP,模型转化。

对每个点计算出到 A,B 的最短路,分别离散化后,令 \(v_i\to (\text{dis}_{A}(i), \text{dis}_B(i))\),即表达在网格图上。

每次 A 的选择是覆盖前几行,而 B 的选择是覆盖前几列。

\(f(i,j,0/1)\) 表示覆盖了前 \(i\) 行,前 \(j\) 列,当前先手是 A/B 的 \(\min/\max\)

如果强行枚举当前先手覆盖的长度,复杂度是 \(O(n^3)\) 的。

发现完全没有必要,因为转移过程本身就遍历了后续所有状态,不间断,所以只考虑 \((i,j)\to (i+1,j)\)\((i,j)\to (i,j+1)\) 即可。

CF538G Berserk Robot

  • 给出 \(n\) 个限制,形如 \((t,x,y)\),表示第 \(t\) 个单位时间机器人在 \((x,y)\)
  • 构造长度为 \(l\) 的 NSEW 序列,表示机器人按照这个序列循环不断移动,满足上述限制,或者判断无解。
  • \(n\leq 2\times 10^5,l\leq 2\times 10^6,t_i,|x_i|,|y_i|\leq 10^{18}\)

虐心题,代码调一上午。

大概思路是求出每 \(l\) 次移动的 \(\Delta x\)\(\Delta y\),之后将每个限制变为 \(((t-1\bmod l)+1,x-\Delta x\times \lfloor\dfrac{t-1}{l}\rfloor, y-\Delta y\times \lfloor\dfrac{t-1}{l}\rfloor)\)

转化到一个循环里,对于新的 \((t',x',y')\),首先时间相同的限制要一样,其次满足两点:

  • \(x'+y'\equiv t'\pmod 2\)
  • \(\forall i,j,t'_i>t'_j\),满足 \(t'_i-t'_j\geq |x'_i-x'_j|+|y'_i-y'_j|\)

这样每次就全力往某个方向走,多余的一定是偶数个,直接反复横跳即可。

关键是,如果不存在初始 \((t-1)\bmod l\) 相等的对,找到 \(\Delta x\)\(\Delta y\) 并不简单。

于是转变思路,用上面的必要条件反向找可行的 \(\Delta x\)\(\Delta y\)

对于奇偶性的限制,直接暴力枚举奇偶性,看是否可行即可。

对于不等式,将所有 \(t,x,y\) 都用上述方法转变为带未知元 \(\Delta x,\Delta y\) 的方程,把 \(|a|+|b|\) 等价拆为 \(\max(a+b,a-b,-a+b,-a-b)\)

然后就得到了一系列 \(\Delta x+\Delta y\)\(\Delta x-\Delta y\) 的限制,枚举 \(\Delta x\in[-l,l]\),根据另一限制和奇偶性找 \(\Delta y\) 即可。

CF538H Summer Dichotomy

  • 给定 \(n\) 个区间,求将区间分为两部分,某一部分可以为空。
  • 使得两部分区间分别有交,且交相加后与 \([t,T]\) 有交。同时有 \(m\) 条两个区间不能在同一部份的限制。
  • \(t\leq T\leq 10^9,n,m\leq 10^5\)

妙妙题。

首先这题看着很 2-sat。先将 \(m\) 条边连接,跑二分图判定,得到黑白两个区间。

这样就相当于对每个连通块,它的两个区间必须分选,特别的,单点只有自己的区间 和 一个空区间,符合 2-sat 模型。

考虑限制,首先每部分区间有交,先把 \(\max l\)\(\min r\) 拿出来。

  • 如果 \(\max l \leq \min r\),说明任意区间集合均有交,且都包含 \([\max l,\min r]\)

    只需要找一个 \(v\),满足 \(v\) 属于某个区间,且 \([\max l+v,\min r +v]\)\([t,T]\) 有交即可,并不难。

  • 如果 \(\max l>\min r\),两者必须分属两个部分。

但是这个思路后续似乎就不明朗了,看过题解后才发现应该直接贪心。

因为 \(\max l\)\(\min r\) 是最松松松的限制了,\(\max l\) 不能变小,\(\min r\) 不能变大。

所以如果 \(\max l+\min r<t\) 就加 \(\max l\)\(>T\) 就减 \(\min r\),然后就令两个点为最终决策点。

对必须选一个的跑二分图染色,不冲突即可。

CF547D Mike and Fish

  • 给定平面内 \(n\) 个点,构造黑白染色使得对任意行或任意列,两颜色差的绝对值 \(\leq 1\)
  • \(n,x_i,y_i\leq 2\times 10^5\)

经典题。

将点表达到边上,行列连边,得到二分图,将奇点统一连向一个虚点,这样图就有欧拉回路了。

对欧拉回路中,从左往右的染白,从右往左的染黑即可。

CF547E Mike and Friends

  • 给定 \(n\) 个字符串。
  • 多次询问 \((l,r,k)\),求 \(s_k\)\(s_l \sim s_r\)中出现了多少次。
  • \(n,\sum |s|\leq 2\times 10^5,q\leq 5\times 10^5\)

论你写完题解后发现一道题的题解通道已关闭(

好像是没有人提出的做法。

因为 \(\text{len} = \sum |s|\leq 2\times 10^5\),所以不同的 \(|s|\) 个数只有 \(O(\sqrt{\text{len}})\) 种,这是经典根号分治。

也就是说,每个串中只有 \(O(|s|\sqrt{\text{len}})\) 个子串有贡献,这是可以接受的。

但是不能把这些子串都塞入 Hashtable 中,MLE 了。

但是也不难,直接将初始的 \(n\) 个字符串塞入 Hashtable 中,每次把子串的贡献加到 \(\text{cnt}_i\) 上(该子串与 \(s_i\) 相等)。

然后离线差分一下就没了,时间复杂度 \(O(n\sqrt n)\)

小彩蛋:一开始写 unsigned long long 自然溢出的 Hash 被 hack 了,CF 果然名不虚传

当然一开始就把所有串扔到 AC 自动机里去,离线标记 + 树状数组维护子树和也很经典了。

好像 SA + 二维数点也很经典了(这就是一套路满满题

CF553E Kyoya and Train

  • 给定有向图,边有代价 \(c\)\(t\) 个概率,分别表示经过这条边花费 \([1,t]\) 个单位时间的概率。
  • 如果在 \(t\) 时刻之后到达 \(n\),需要交 \(x\) 元罚款。求最优决策下,从 \(1\to n\) 的期望最小代价。
  • \(n\leq 50,m\leq 100,t\leq 2\times 10^4,x,c_i\leq 10^6\)

科技题。

一开始想了很久正着 DP,突然发现目标明确直接逆着 DP 就好了。

\(f(u,i)\) 表示 \(i\) 时刻到达 \(u\),从 \(u\to n\) 还要花费的最小期望代价。

  • \(f(n,*)=[i>t]x\)
  • \(f(*,t+1)=\text{dis(*,n)}\)。(最短路)
  • \(\displaystyle f(u,i)=\min_{(u,v,w)\in E} \left( \sum_{i=1}^{t} p_{u,i}\times f(v,i+t)\right)\)

然后直接差卷积 FFT,发现转移没有单调性,所以用 SPFA。看题解区据说复杂度并非 \(O(nmt\log t)\) 的,但是能过也不知道咋卡。

正解是分治 FFT,也不知道是啥科技(

CF555E Case of Computer Network

  • 给定无向图,判断是否能将边定向使得给出的 \(q\)\((s,t)\) 都存在 \(s\to t\) 的路径。
  • \(n,m,q\leq 2\times 10^5\)

结论题。

老早就被灌输过一个 边双一定能定向为强连通分量 的结论,没想到还真能拿来出题。

直接边双缩点 + 给树上路径定向即可。实现时我还用了树上并查集,实际直接差分即可。

这个结论的证明:

考虑找到边双中任意一个环,并统一定向。

然后找到边 \((u,v)\) 使得 \(u\) 在环中但 \(v\) 不在,如果找不到说明整个边双已经是强连通分量了。

然后就找到 \(v\) 到环,但是不经过 \((v,u)\) 这条边的路径,并将这条链统一定向,融入视为“环”的一部分。

一定能成功,因为边双 \(v\to u\) 至少有两条路径,也自然有 \(v\) 到环的路径。

CF559E Gerald and Path

  • 给定 \(n\) 条线段,给出它的一个端点和长度,求所有线段覆盖的最大长度。
  • \(n\leq 100\)

厉害题。

一开始的想法是:先将线段按给定端点排序,设 \(f(i,j,0/1)\) 表示从前往后考虑到了 \(i\),当前最右端是 \(j\)\(j\) 的状态是往左/右。

然后转移的时候只考虑最右端点往右的贡献,因为(我认为),如果往左右贡献只能是完全包含先前线段,那还不如先前线段不被加入。

实际有严重问题,那就是先前线段可能有往右的贡献!!!

解决方法,同样的状态,类似的转移,但是当 \(f(i,j,k)\to f(o,p,q)\) 的时候,还考虑 \([i+1,o]\) 中最右端点 \(p\) 的贡献。

实际上很顺理成章的嘛,因为本身状态就这么设计的,连最右端的贡献都不计入怎么行(

只能说是核心思路想到了但实现出大问题。

CF566C Logistical Questions

  • 给定一棵树,有点权边权。
  • \(u\to v\) 的距离定义为 \(a(v)\times \text{dis}^{\frac{3}{2}}(u,v)\),求树的带权重心。
  • \(n\leq 2\times 10^5\)

不会求导ing

对于一类带权重心的经典解法就是调整法,每个时刻至多存在一条边,使得往该子树移动的带权重心减小。

原因是距离函数是下凸的,多个下凸函数的叠加还是下凸的。

问题是如何快速判断往哪个子树移动,之后可以用经典点分治多个 \(\log\) 解决。

看式子,沿着边 \((u,v,w)\) 移动的结果是:

\[\sum_{x\in\text{subtree}(v)} a_x(\text{dis}(u, x)-w)^{\frac{3}{2}}+\sum_{x\not \in\text{subtree}(v)} a_x(\text{dis}(u,x)+w)^{\frac{3}{2}} \]

如果往一个方向的函数值会减小,那么对它求导看哪个 \(<0\) 即可,即观察:

\[-\frac{3}{2}\sum_{x\in\text{subtree}(v)} a_x\sqrt{\text{dis}(u, x)}+\frac{3}{2}\sum_{x\not \in\text{subtree}(v)} a_x\sqrt{\text{dis}(u,x)} \]

的正负性。

CF566E Restoring Map

  • 给定树上 \(n\) 个点的点集,各自的点集均由距离自己 \(\leq 2\) 的所有点构成。
  • 并不知道每个集合对应哪个点,要求构造原树。
  • \(n\leq 10^3\)

这种题目就是要 dfs 式的找性质。

发现距离为 \(3\) 的节点的交集大小恰好 \(=2\),且这两个点一定直接连边。

因此除了 \(n=2\)(直接特判)的情况,所有非叶子节点直接的连边都能确定。

如果出现非叶子节点个数 \(=2\) 的情况,不能通过集合区分叶子,但只会有两类叶子集合,分别挂在不同节点上即可。

否则对于叶子节点,能够确定它对应的集合,就是所有包含它的集合中,大小最小的一个。

要找到叶子的父亲,就是看只保留非叶子节点时,哪个集合与之相等。全程判断需要用 bitset 优化。

学会了遍历 bitset 的正确姿势:

for(int k = now._Find_first(); k != now.size(); k = now._Find_next(k))

CF568C New Language

  • \(\texttt{a}\) 开始的 \(l\) 个字符分为两个集合。
  • 利用这 \(l\) 个字符构造满足 \(m\) 个限制的长度为 \(n\) 的字符串。还要求构造串的字典序不小于给定串 \(s(|s|=n)\)
  • 每个限制形如:若 \(p_1\) 上的字符 \(\in\) 集合 \(t_1\),那么 \(p_2\) 上的字符 \(\in\) 集合 \(t_2\)
  • \(l\leq 26, n\leq 200,m\leq 4n(n-1)\)

一眼 2-sat + 按位贪心。

CF568E Longest Increasing Subsequence

  • 给定长度为 \(n\) 的序列,有 \(k\) 个空缺。给定 \(m\) 个数用于填补空缺。
  • 输出严格上升子序列最大的方案。
  • \(n\leq 10^5,k\leq m\leq 10^5,k\leq 10^3\)

考虑求严格上升子序列的 \(O(n\log n)\) 做法,维护的是当前长度为 \(i\) 的上升子序列的最小末尾。

在这里发现可以在每个空缺直接把 \(m\) 个数都插进去,因为严格上升代表转移不重。每次双指针就是 \(O(n+mk)\) 的。

个人认为最大难度在方案输出。

逆向构造是一定的,需要记录 \(f(i)\) 表示 \(i\) 位置的上升子序列,非空缺能够直接记录个 \(\text{pre}\)

空缺先看能否转移到非空缺,如果不能就贪心的用最大的一个数填补。

CF571D Campus

  • 维护两类集合和一个序列,初始每类 \(n\) 个集合,\(i\) 号集合下有且仅有 \(i\)。支持 \(5\) 种操作:
    • U x y:将第一类中 \(x,y\) 所在集合合并。
    • M x y:将第二类中 \(x,y\) 所在集合合并。
    • A x:将第一类中 \(x\) 所在集合的下标在序列中均对应加上该集合大小。
    • Z x:将第二类中 \(x\) 所在集合的下标在序列中均赋值为 \(0\)
    • Q x:单点查询。
  • \(n,m\leq 5\times 10^5\)

维护一个点加入集合的时间,就有一个显然的 \(O(n\log ^2 n)\) 的并查集做法了。

CF573E Bear and Bowling

  • 给定长度为 \(n\) 的序列 \(a\),求最大权值子序列 \(b\)
  • 子序列的权值定义为 \(\sum_{i=1}^{|b|} ib_i\)
  • \(n\leq 10^5,|a_i|\leq 10^7\)

\(O(n^2)\) 的 DP 式是很好得到的,之后就比较难动手,考虑了一会转移到网格图上。

然后突然发现转移的单调性,就是一定有一个位置,使得 \(f(i,j)\) 之前的 \(j\) 是继承,之后的 \(j\) 是转移。

这样相当于需要在线维护 后缀加等差数列 和 单点查询。

这里我傻了,想了半天会了一个 平衡树 + 矩阵 的维护方法, 虽然更有普适性但是 1min 的时间真的不如写卡常的暴力(

实际上差分就变成后缀加了,每次查询前缀和即可 QwQ

CF575A Fibonotci

  • 对于序列 \(f\)\(f_0=0,f_1=1\)\(f_i=s_{i-1}f_{i-1}+s_{i-2}f_{i-2}\)
  • \(s_0\sim s_{n-1}\) 给定,之后有 \(m\) 个位置的 \(s_i\) 也给定,其余 \(s_i=s_{i\bmod n}\)
  • \(f_k\bmod p\)
  • \(n,m\leq 5\times 10^4,k\leq 10^{18},s_i,p\leq 10^9\)

一开始傻了不知道怎么用一个矩阵表示 \(n\) 个转移。实际上用 \(n\) 个矩阵即可……

\(n\) 个矩阵倍增预处理,对给定位置特殊处理即可。

实现上的一个细节是连续的给定位置会对矩阵有连续的影响,要同时考虑。

CF575E Spectator Riots

  • 给定多个图形,每个图形中随机撒一个点。
  • 在所有给定图形中找 \(3\) 个点,使得它们的外接圆期望覆盖的点尽量多。
  • 如果有多个方案输出外接圆半径最大的,还有就任意输出。
  • \(n\leq 10^5\)

题面是骗人的,实际一定存在覆盖所有图形的方案。

考虑一个无限大的圆不断缩小,直至接触到凸包上至少 \(3\) 个点。如果 \(3\) 个点不相邻那肯定移动到相邻覆盖范围更严格大。

所以感性理解以下在凸包上找 \(3\) 的相邻点的最大外接圆半径即可~

CF575I Robots protection

  • 维护二维平面 \((0,0)\sim (n,n)\),支持两种操作:
    • 加入一个两条直角边平行于坐标轴的等腰直角三角形。
    • 询问一个点被多少个三角形覆盖。
  • \(n\leq 5\times 10^3,m\leq 10^5\)

直接做是 \(4\) 维偏序,不能通过。值域这么小显然是用来给二维树状数组的,所以目标是优化到 \(3\) 维偏序。

由于图形是对称的所以只考虑一种,发现可以简单容斥,如图:

image.png

可以先把 \(AB\) 以右的一个矩形 \(+1\)\(x_0\in [x,n],y_0\in[y,y+\text{len}]\))。

再把多余部分 \(-1\)\(x_0+y_0>x+y+\text{len},y_0\in[y,y+\text{len}]\))。

其余几种也都是这种形式。

CF576D Flights for Regular Customers

  • 给定一张 \(n\) 个点 \(m\) 条边的有向图。一开始在 \(1\) 号节点,要走到 \(n\) 号节点。
  • 只有当你已经走过了至少 \(d_i\) 条边时,你才能走第 \(i\) 条边。
  • 问最少要走多少条边,或判断无法到达。
  • \(n,m \le 150\)\(d_i \le 10^9\)

经典矩阵乘法,每次单边激活即可。

CF576E Painting Edges

  • 给定一张 \(n\) 个点 \(m\) 条边的无向图。
  • 一共有 \(k\) 种颜色,一开始,每条边都没有颜色。
  • 定义合法状态为仅保留染成 \(k\) 种颜色中的任何一种颜色的边,图都是一张二分图。
  • \(q\) 次操作,第 \(i\) 次操作将第 \(e_i\) 条边的颜色染成 \(c_i\)
  • 但并不是每次操作都会被执行,只有当执行后仍然合法,才会执行本次操作。
  • 你需要判断每次操作是否会被执行。
  • \(n,m,q \le 5 \times 10^5\)\(k \le 50\)

有些新意但是还是很板的线段树分治,可以看作是假的强制在线,按时间顺序走即可。

CF578E Walking!

  • 给定长度为 \(n\) 的只包含 LR 的字符串 \(s\)
  • 构造 \(n\) 的排列 \(p\) 满足 \(s_{p_i}\neq s_{p_{i+1}},i\in[1,n)\),同时最小化 \(\sum_{i=1}^{n-1}[p_i>p_{i+1}]\)
  • \(n\leq 10^5\),保证数据有解。

中规中矩的构造题。

得到答案相对简单,维护所有候选集合,如果当前字符能够加到某个集合末尾就直接加,否则只能新开一个。

答案就是集合数 \(-1\),比较关键的是构造。

集合内部和构造无关,根据集合首尾定义 \(4\) 种集合:LLLRRLRR

首先让 LRRL 们合并成至多一个自己种类,同时 LLRR 拼接消耗。

注意因为一定有解,所以 LLRR 两种导致一种字符比另一种多一个的在互相拼接消耗后,一定一共只剩下一个。

如果它此时存在的话就只需要将 LRRL 分别拼接在两端。

否则只有一种情况比较棘手,那就是只剩下一个 LR 和一个 RL

但此时根据讨论可以将一个串的开头放到另一个串的开头,从而形成 LLRR 的局面,于是问题解决了。

CF582D Number of Binominal Coefficients

  • 给定质数 \(p\) 和整数 \(\alpha ,A\),求满足 \(0\leq k\leq n\leq A\)\(p^{\alpha}|\binom{n}{k}\) 的数对 \((n,k)\) 的个数。
  • \(p,\alpha\leq 10^9,A<10^{1000}\)

感觉像Kummer 定理这种的定理也就只能出现在数位 DP 中 QwQ

也就是说 \(\binom{n}{k}\)\(p\) 的幂次等于 \(p\) 进制下 \(k+(n-k)\) 的进位次数,或者令 \(a=k,b=n-k\) 然后等价统计二元组 \((a,b)\) 的个数。

\(f_{i,j,0/1,0/1}\) 表示考虑到了从高到低第 \(i\) 位,进位了 \(j\) 次,第 \(i+1\) 位是否进位,\(a+b\) 是否顶到上界的方案数。

DP 的细节还是有的,有些系数甚至比较难推,举一例。

\(a',b'\) 分别表示 \(a,b\)\(i\) 位的数字,满足 \(0\leq a',b'<p\),求 \(p\leq a'+b'<p+x_i\),即进位且受 \(A\) 的限制但之后 \(<A\) 的方案数。有:

\[\begin{eqnarray} \text{ans} &=& \sum_{i=p}^{p+x_i-1}\sum_{a'=0}^{p-1}\sum_{b'=0}^{p-1} [a'+b'=i] \nonumber\\ ~&=& \sum_{i=p}^{p+x_i-1}\sum_{a'=0}^{p-1}[0\leq i-a'<p] \nonumber\\ ~&=& \sum_{a'=0}^{p-1} \sum_{i=p}^{p+x_i-1}[i<p+a'] \nonumber\\ ~&=& \left(\sum_{a'=0}^{x_i-1} a'\right)+\left(\sum_{a'=x_i}^{p-1} x_i\right) \nonumber\\ ~&=& \dfrac{x_i\times (x_i-1)}{2} + (p-x_i)\times x_i \nonumber \end{eqnarray} \]

其它系数大概也就这个级别的推导,不过有 \(6\) 个……

CF582E Boolean Function

  • 给定表达式,只有 \(A,B,C,D,a,b,c,d\) 八个 bool 变量,且大小写字母相反。以及 &| 两种操作符。
  • 给定一个表达式,变量和操作符均可能是 ? 表示通配。
  • 给定 \(m\leq 16\)\((A,B,C,D,x)\) 表示当 \(A,B,C,D\) 取值如此时,表达式的值为 \(x\)
  • 求合法的表达式个数。
  • \(|s|\leq 500,n\leq 16\)

建立表达式树,直接对 \(16\) 种状态状压,然后 fwt 维护转移即可,复杂度 \(O(|s|n2^{n})\)

CF585E Present for Vitalik the Philatelist

  • 给定长度为 \(n\) 的序列 \(a_i\),求二元组 \((x,S)\) 的个数。\(S\) 是一个包含 \([1,n]\) 中整数的非空集合,\(x\) 也是一个 \(\in[1,n]\) 的整数。
  • 满足:\(x\not \in S\)\(\gcd _{i\in S} a_i>1\)\(\gcd(a_x,\gcd_{i\in S}a_i)=1\)
  • \(n\leq 5\times 10^5\)

一开始看错题了还想了挺久(

比较套路的拿 \(\mu\) 作容斥系数即可,每个数至多贡献 \(2^8\)\(\mu\) 有值的位置,所以复杂度挺优秀的。

CF585F Digits of Number Pi

  • 给定字符串 \(s\),以及 \(d\) 位数 \(x,y\),求有多少 \(t\in[x,y]\)\(t\) 有长度至少为 \(\lfloor\frac{d}{2}\rfloor\) 的子串是 \(s\) 的子串。
  • \(|s|\leq 10^3,d\leq 50\)

\(s\) 的所有长度为 \(\lfloor\frac{d}{2}\rfloor\) 的子串建立 ACM,直接数位 DP 即可。

CF587D Duff in Mafia

  • 给定无向图,每条边有边权和颜色。
  • 要求选出一组边,满足他们是一个匹配,且剩下的每种颜色的边也都构成匹配。
  • 同时最小化选出的边权最大的边的边权,并输出。
  • \(n,m\leq 5\times 10^4\)

盯了挺久没有思路的,属实是傻了。

首先二分答案,然后每个顶点至少选一条边,每种颜色每个顶点处也至多选一条边,不是显然的 2-sat 的模型吗!!!

在每个顶点处前后缀和以下应该是挺好些的。

实际上每种颜色的边们可以直接暴力建,因为如果一个顶点处有 \(\geq 3\) 条同色边一定无解嘛。

CF587F Duff is Mad

  • 给定 \(n\) 个字符串,多次询问 \(s_{l...r}\)\(s_k\) 中出现了多少次。
  • \(n,q,\sum_{i=1}^n |s_i|\leq 10^5\)

一眼看成 CF547E QwQ

那题我就是拿根号分治过的,这里思考了以下发现之前的思路并不可行了,然后逐渐自闭。

实际上还是考虑根号分治,根据 \(|s_k|\) 分类,设 \(m=\sum |s_i|\)

  • 对于 \(|s_k|>\sqrt m\) 的:

    因为这种串的个数很少,所以每次可以 \(O(m)\)。给 \(s_k\) 上的点标记,在 ACM 上预处理每个点的子树内的标记个数。

    然后直接前缀和一下就能得到任意区间的答案了。

  • 对于 \(|s_k|\leq \sqrt m\) 的:

    可以 \(O(|s_k|)\) 就更简单了,考虑每个位置的贡献,只需要差分一下,每次 \(s_i\) 的子树 \(+1\) 即可。

    根号平衡一下能做到 \(O(\sqrt m)\) 子树加和 \(O(1)\) 查询。

总时间复杂度 \(O(m\sqrt m)\)

CF590E Birthday

  • 给定 \(n\) 个字符串,保留尽量多的字符串,使得不存在一个字符串是另一个的子串。
  • \(n\leq 750,\sum|s_i|\leq 10^7\),输出方案。

一眼根据 ACM 建立偏序集然后 Dilworth 最长反链,处理时只需要路径压缩。

需要注意的是当递归层数大到一定程度时,一定考虑递归栈的大小,例如这里 \(10^7\) 就一定不要写任何相关的 dfs。

然后人傻了不会 Dilworth 方案输出,编了好久网络流才猛然想起蓝书上都讲过……属实是基础不过关。

大体就是个调整法,一定有解什么的也挺好反证的。

传递闭包用 bitset 优化,如果匹配写个网络流的话,因为调整只需要 \(O(n^2)\),所以总时间复杂度是 \(O(\dfrac{n^3}{\omega }+n^2\sqrt n)\)

CF603E Pastoral Oddities

  • 给定一张 \(n\) 个点的无向图,初始没有边。
  • 依次加入 \(m\) 条带权的边,每次加入后询问是否存在一个边集,满足每个点的度数均为奇数。
  • 若存在,则还需要最小化边集中的最大边权。
  • \(n \le 10^5\)\(m \le 3 \times 10^5\)

充要条件是所有连通块都有偶数个点,考虑经典 dfs 树构造。

至于最小化最大边权,只需要用考虑 Kruscal 的方式,不断按边权从小到大加入边即可。

考虑到动态加边,利用 LCT 维护最小生成树的方式(边化点然后维护链的边权最大值)。

用一个堆维护当前生成树内的边集,再利用 LCT 维护子树和那一套维护每个连通块点数的奇偶性即可……

听起来和写起来都挺 shit 的,算是 LCT 大融合了,为的就是那一只 \(\log\) QwQ

否则有一个可以完全和 LCT 无关的 分治 + 并查集的 两 \(\log\) 做法。实测下来 LCT 的巨大常数完全打不过下面的好吧

CF605E Intergalaxy Trips

  • 给定 \(n\) 个点的竞赛图,走过一条边需要一天,每条边每天出现的概率均为 \(p_{i,j}\)
  • 保证 \(p_{i,i}=1\),即可以在某个点等待。
  • 求最优决策下 \(1\to n\) 的期望天数。
  • \(n\leq 1000\)

显然是设 \(E_i\) 表示 \(i\to n\) 的期望天数。

假设已知 \(E_i\) 的大小关系并将它们升序排序,那么每次的决策显然是从小到大选择第一个存在的边,同时如果 \(E_v>E_u\) 显然不如等待。

即:

\[E_u=\left(\sum_i E_{v_i} p_{u,v_i} \prod_{j=1}^{i-1} (1-p_{u,v_j})\right) + \left(E_u\prod_i (1-p_{u,v_i})\right)+1 \]

移项得到最终结果:

\[E_u=\frac{\left(\sum_i E_{v_i} p_{u,v_i} \prod_{j=1}^{i-1} (1-p_{u,v_j})\right)+1}{1-\prod_i (1-p_{u,v_i})} \]

问题是一开始只知道 \(E_n=0\),其余点不知道。

其实只需要利用类似 \(O(n^2)\) 的 Dijkstra 的思路,每次选择最小的 \(E\) 贡献给其余,动态维护每个未确定的 \(E_u\) 即可。

CF611H New Year and Forgotten Tree

  • 给定每条边两端点 \(10\) 进制下的位数,构造对应的原树,或输出无解。
  • \(n\leq 2\times 10^5\)

有点好玩,感觉这个 idea 很神奇。

想了很多基于贪心的构造,但实际上需要一个核心观察:

将每种位数取一个关键点,如果合法,总存在一种构造使得这些关键点构成一棵子树,其余点均挂在关键点下。

关键点只有 \(m\leq 5\) 个,于是直接 \(O(m^{m-2})\) 枚举树的形态,然后就是一个二分图多重匹配。

CF613E Puzzle Lover

  • 给定 \(2\times n\) 的字母矩阵,同时给定长度为 \(k\) 的字符串 \(s\)
  • 求有多少长度为 \(k\) 的有向路径,使得不经过重复格子,且按顺序构成了 \(s\)
  • \(n,k\leq 2000\)

发现如果路径回头就没救了,所以一定是两端一个 U 形,然后中间蛇形路线(

因为路径有向直接钦定从左往右走然后 reverse 再做一遍,注意当 \(k\leq 2\) 时需要去重。

预处理 Hash 就能轻易得到左边的起始 U 形,中间则是简单的线性 DP,注意不重即可。

CF626G Raffles

  • \(n\) 种彩票,第 \(i\) 种有价值 \(p_i\),别人已经买了 \(l_i\) 张。
  • 你可以买 \(m\) 张彩票。假设第 \(i\) 种买了 \(c_i\) 张,需要满足 \(c_i\leq l_i\)
  • 最大化 \(\sum \frac{c_i}{c_i+l_i} p_i\)
  • 每次修改会有 \(l_i\pm 1\),保证时刻有 \(l_i\geq 1\)
  • \(n\leq 2\times 10^5\)

简单题。

静态的只需要一个堆维护 \(\max \Delta\) 即可,因为这是个减函数。

修改时也很容易发现只需要将当前决策中最小的 \(\Delta\) 不断拿出来比较即可,可以证明每次这样的修改都是 \(O(1)\) 的。

posted @ 2022-06-23 16:27  LPF'sBlog  阅读(215)  评论(0编辑  收藏  举报