杂题20210203
CF1466G Song of the Sirens
给定由小写字母构成的字符串 \(s_0\) 和 \(t\ (|t|=n)\) ,对于 \(1\leq i<n,\ s_{i+1}=s_it_is_i\)
有 \(q\) 次询问,每次给定 \(k\) 和一个串 \(w\) ,求出 \(w\) 在 \(s_k\) 中的出现次数
模 \(10^9+7\)
\(n, q\leq10^5\)
\(|s_0|\leq100;\ \displaystyle\sum|w|\leq10^6\)
对于询问,考虑求出对 \(s_i\ (1\leq i\leq k)\) 求出 \(w\) 跨越其中心的出现次数 \(x\) ,对答案的贡献为 \(2^{k-i}x\)
考虑最小的满足 \(|s_p|\ge|w|\) 的 \(p\) 。对于 \(|s_q|\ (q>p)\) ,其构造形如 \(s_p+t_p+s_p+\cdots+s_p+t_{q-1}+s_p+\cdots+s_p+t_p+s_p\) ,由于 \(|s_p|\ge|w|\) ,我们只用考虑 \(w\) 的某个前 / 后缀与 \(s_p\) 的某个前 / 后缀是否匹配
那么我们枚举 \(w\) 的一个位置 \(r\) ,统计用 \(r\) 匹配 \(t_{q-1}\) 时的贡献,可以用 hash 或 exkmp 判断与 \(w\) 的匹配关系
时间复杂度 \(O(n\log n)\)
TC13368 OnePointNineNine
给定平面上 \(n\) 个整点和常数 \(D\) ,保证任意两点之间的欧几里得距离要么 \(\leq D\) ,要么 \(\ge1.99\times D\)
求有多少个点集的子集 \(S\) 满足,对于任意 \(x,\ y\in S\ (x\neq y)\) ,存在 \(dist(x,\ y)\ge1.99\times D\)
答案模 \(10^9+7\)
\(n\leq1000\)
记 \(G_{i,\ j}=[dist(point_i,\ point_j)\leq D]\) ,即独立集计数
将所有连通块分开考虑,若是一个团,答案显然,否则必然存在三个点 \(A,\ B,\ C\) 满足 \(G_{A,\ B}=G_{B,\ C}=1,\ G_{A,\ C}=0\) ,则 \(A,\ B,\ C\) 近似形成了一条直线,在 \(B\) 附近可能有一些点,而距离 \(B\) 一定范围内一定不存在其它点(例如 \([0.1D,\ 0.9D]\) ),不然这个点就与 \(A\) 或 \(C\) 距离在 \((D,\ 1.99D)\) 之间了。因此我们将距离 \(B<0.1D\) 的点们缩起来,继续考虑
可以发现最后必定会缩成若干个环或者链,统计一下即可
CF1473F Strange Set
给定两个序列 \(a_1,\ a_2,\ \cdots,\ a_n\) 和 \(b_1,\ b_2,\ \cdots,\ b_n\)
定义一个集合 \(S\subseteq\{1,\ 2,\ \cdots,\ n\}\) 是合法的,当且仅当对于任意 \(i\in S\) ,满足 \(j\in[1,\ i),\ a_i\bmod a_j=0\) 的 \(j\) 都存在于集合 \(S\)
定义集合 \(S\) 的权值为 \(\displaystyle\sum_{i\in S}b_i\) ,问最大可能权值
- \(n\leq3000\)
- \(a_i\leq100\)
- \(|b_i|\leq10^5\)
空间限制 32MB
将 “选了 \(i\) 就必须选 \(j\) ” 的限制看作一条 \(i\to j\) 的有向边,那么现在即求:给一张带点权的 DAG,选了点 \(i\) ,则 \(i\) 的子 DAG 内的点必须被选择,问选择方案的点权和最大值
从最小割的角度考虑
若有限制 \(i\to j\) ,则我们从 \(i\) 向 \(j\) 连一条流量为 \(\inf\) 的边,即不能割掉
若 \(b_i\ge 0\) ,我们从源点向 \(i\) 连一条流量为 \(b_i\) 的边
若 \(b_i<0\) ,我们从 \(i\) 向汇点连一条流量为 \(b_i\) 的边
答案即为 \(\displaystyle\sum_{i=1}^n\max(b_i,\ 0)\) 减去 最大流
注意到 \(a_i\) 值域范围不大,我们在考虑限制 \(i\to j\) 时,继承一下 \(lst_i\to j\) 的连边即可,其中 \(lst_i\) 是满足 \(k<i,\ a_k=a_i\) 的最大的 \(k\) ,这样最多会建 \(O(na_i)\) 条边
TC11940 SequenceTransmission
记 \(f(x)=ax+b\) ,将 \(f(x)\) 于 \(x=1,\ 2,\ \cdots,\ n\) 的取值的无前导零二进制表示依次排在一起,问其连续段个数
如 \(a=3,\ b=5,\ n=4\) 时, \(f(x)\) 的取值依次为 \(8,\ 11,\ 14,\ 17\) ,其二进制表示的排列为 \(10001011111010001\) ,共 \(8\) 个连续段
\(1\leq a\leq4\times10^4,\ 1\leq b\leq10^{18};\ n\leq10^{12}\)
考虑对所有取值的二进制表示分别计算其连续段个数,减去相邻取值二进制表示首尾相同的个数
做法一:
\(f(x)\) 取值的集合可以看作 \(\{x\ |\ x\equiv b\pmod a\}\cap[a+b,\ a\times n+b]\cap\mathbb Z\)
考虑数位 dp,用 \(x\leq a\times n+b\) 的答案减去 \(x<a+b\) 的答案
记 \(F_{i,\ j,\ k,\ 0/1,\ 0/1}\) 为,考虑了高 \(i\) 位,当前数 \(\equiv j\pmod a\) ,上一位填的是 \(k\) ,截至目前是否是前导零,是否卡到上界,满足这些条件的数目前的连续段个数之和
还需要记一个 \(G_{i,\ j,\ k\ 0/1,\ 0/1}\) 表示满足这些条件的数的个数,用以辅助转移
如果要卡空间可以写成递推的形式,并使用滚动数组
做法二:
我们考虑第 \(i\) 位在什么时候会对答案产生 \(1\) 的贡献
若 \(i+1,\ i\) 位形如 \(01,\ 10\) 则有贡献,形如 \(00,\ 11\) 则没有贡献
然后搞一搞就得到了类欧的形式((
大概可以做到 \(\log^2\)
TC16346 TwoPerLine
在 \(n\times n\) 的棋盘上放恰好 \(k\) 个棋子,一个位置至多放一个,每行每列至多放两个,问方案数模 \(10^9+7\)
\(n\leq200,\ 0\leq k\leq 2n\)
建一个左右点数均为 \(n\) 的二分图,左侧 \(n\) 个点代表每一行,右侧 \(n\) 个点代表每一列;将在位置 \((i,\ j)\) 放一颗棋子看作连接左部点 \(i\) 和右部点 \(j\) 的边。那么现在问题变为:统计有多少个左右点数均为 \(n\) 的无重边二分图,恰有 \(k\) 条边,且每个点度数不超过 \(2\)
有一个 naive 的 dp 做法:
记 \(f_{i,\ j,\ l_1,\ r_1}\) 为,仅考虑了左部前 \(i\) 个点和右部的 \(n\) 个点,当前有 \(j\) 条边,且左部当前有 \(l_1\) 个度数为 \(1\) 的点,右部有 \(r_1\) 个度数为 \(1\) 的点,此时的方案数
那么有 \(\displaystyle\begin{cases}l_0+l_1+l_2=i\\l_1+2l_2=j\end{cases}\) 和 \(\displaystyle\begin{cases}r_0+r_1+r_2=n\\r_1+2r_2=j\end{cases}\) ,其中 \(l_0\) 为左部前 \(i\) 个点中度数为 \(0\) 的点的个数, \(l_2,\ r_0,\ r_2\) 同理
转移时枚举第 \(i+1\) 个左部点连出多少条边,分别向哪些右部点连
时间复杂度 \(O(n^3k)\) ,无法通过
我们记 \(f_{i,\ l_1,\ r_1}\) ,为还剩 \(i\) 条边没有连,左部当前有 \(l_1\) 个度数为 \(1\) 的点,右部当前有 \(r_1\) 个度数为 \(1\) 的点
这样转移可能会导致出现重边,考虑容斥,我们枚举有 \(t\) 对点连了两条边,那么答案为:
其中 \(\displaystyle\frac1{k!}\) 去掉连边顺序的贡献, \(\displaystyle\binom{n}{t}^2t!\) 是选出 \(t\) 对点的方案数, \(\displaystyle\frac{\binom{m}{2i}(2i)!}{2^i}\) 是将这 \(2i\) 条非法边的可重排列塞到连边序列中的方案数
时间复杂度 \(O(n^2k)\)
GYM101620E [CERC2017]Embedding Enumeration
给定一棵 \(n\) 个点,以 \(1\) 为根的树
将其放入一个行数为 \(2\) 的网格图中,要求:
- \(1\) 在左上角
- 若有边 \((u,\ v)\) ,则 \(u\) 在网格图中与 \(v\) 四相邻
- 两个不同的点不能放在同一个格子中
求方案数。答案模 \(10^9+7\)
\(n\leq3\times10^5\)
记 \(f_u\) 为仅考虑 \(u\) 的子树中的节点时的答案(需要满足 \(u\) 在左上角)。而可能存在一些方案,使得对于某个 \(u>1\) , \(u\) 不是它子树形成的图形的左上角,这部分的贡献我们放在 \(u\) 的祖先处考虑。
若 \(u\) 的儿子数 \(>2\) ,则 \(f_1=0\)
若 \(u\) 没有儿子, \(f_u=1\)
若 \(u\) 恰有一个儿子 \(v\) ,有以下几种情况:
- 将 \(v\) 摆在 \(u\) 右侧,且 \(u\) 下方没有节点,有 \(f_v\) 种方案
- 将 \(v\) 摆在 \(u\) 下边。若 \(v\) 有两个儿子,方案数为 \(0\) ;若 \(v\) 有一个儿子,方案数为 \(f_{son_v}\) ;若 \(v\) 没有儿子,方案数为 \(1\)
- \(v\) 在 \(u\) 右侧,且存在一条 \(u\) 子树内的特殊链,它于 \(u\) 的下方终止。我们记 \(\begin{aligned}lst_u=\begin{cases}u\ &(\text{u有零个或两个儿子})\\ lst_{son_u}\ &(\text{u有恰好一个儿子})\end{cases}\end{aligned}\) ,若 \(lst_u\) 是叶节点,当 \(u\) 到 \(lst_u\) 路径上节点数为偶数时对答案有 \(1\) 的贡献;否则, \(lst_u\) 必定是特殊链的两个拐点之一,我们讨论一下即可
若 \(u\) 有两个儿子 \(ls,\ rs\) ,不妨假设 \(ls\) 的儿子个数最多,有以下几种情况:
- 两个儿子均有两个儿子,方案数为 \(0\)
- 儿子 \(ls\) 有两个儿子,那么它只能放在 \(u\) 的右侧,而儿子 \(rs\) 需摆在 \(u\) 下方,且不能有儿子。方案数为 \(dp_{ls}\)
- 儿子 \(ls\) 有一个儿子,有两种情况:将 \(ls\) 放在 \(u\) 下方;将 \(ls\) 放在 \(u\) 右侧。两种情况本质相同
- 儿子 \(ls\) 没有儿子,方案数为 \(2\)
时间复杂度 \(O(n)\)
ARC066C Addition and Subtraction Hard
给定一个由 \(n\) 个正整数和 \(n-1\) 个正负号连接而成的表达式,问在其中加入若干对括号所能得到的表达式的值的最大值
\(n\leq10^5\)
不难发现,我们只会在一个负号后添加左括号,且一定存在一种最优方案使得一个数最多被两层括号所包含
直接 dp 即可
CF643D Bearish Fanpages
给定一棵 \(n\) 个点的基环树, \(i\) 向 \(f_i\) 连有一条边,点 \(i\) 有权值 \(t_i\)
定义点 \(i\) 的控制点集为所有与其距离不超过 \(1\) 的点,即 $i,\ f_i,\ $ 所有满足 \(f_j=i\) 的 \(j\) 构成的集合
发生一次神秘事件后,每个点有初始为 \(0\) 的新权值 \(t_i'\) 。记 \(i\) 的控制点集 \(S\) 大小为 \(k\) ,则 \(i\) 会将 \(j\in S,\ j\neq i\) 的新权值 \(t_j'\) 加上 \(\lfloor\frac{t_i}k\rfloor\) ,将 \(i\) 的新权值 \(t_i'\) 加上 \(t_i-(k-1)\times\lfloor\frac{t_i}k\rfloor\)
注意一次神秘事件并不会影响初始权值 \(t_i\) ,并且神秘事件的发生是相互独立的
现有 \(q\) 次操作,有以下三种类型:
1 i j
,将 \(f_i\) 置为 \(j\)2 i
,问发生神秘事件后,第 \(i\) 个点的新权值3
,问发生神秘事件后,所有点新权值中最小值和最大值保证任意时刻不存在长度小于 \(3\) 的环
- \(n,\ q\leq10^5\)
- \(1\leq t_i\leq10^{12}\)
大概可以将操作简化为:
- 基环树上 link / cut
- 将 \(u\) 的点权增加 \(x\) / 将所有与 \(u\) 有直接连边的点的点权增加 \(x\)
- 询问 \(u\) 点权 / 询问全局点权最值
将所有与 \(u\) 有直接连边的点的点权增加 \(x\) ,单独考虑该操作对 \(u\) 和 \(f_u\) 的贡献,给点集 \(S_i=\{j\ |\ f_j=i\}\) 打 \(+x\) 的 tag
这样能方便地解决单点询问点权
解决全局点权最值可以考虑用 multiset 维护每个 \(S_i\) 的最值形成的集合
不是很好写
Luogu7246 手势密码
有一棵 \(n\) 个点的带点权树。定义一次操作为选择树上的一条简单路径,并将这条简单路径上的所有点点权减去 \(1\) 。问至少需要多少次操作,使树上所有点的点权恰好变为 \(0\) 。
\(n\leq3\times10^6\)
自底向上贪心,对于节点 \(u\) ,我们已经求出了其每个儿子 \(v\) ,能延伸出多少条 待匹配路径
记 \(u\) 所有儿子的 待匹配路径 条数之和为 \(s\) ,最大值为 \(mx\)
我们会尽量让 待匹配路径 们在节点 \(u\) 处匹配,即 将属于不同儿子的两条 待匹配路径 匹配,则匹配个数 \(t\) 为 \(\max(0,\ \min(a_u,\ s-a_u,\ \lfloor\frac s2\rfloor,\ s-mx))\)
第二项的含义是,若还没拿去匹配的 待匹配路径 个数 \(x\) 不多于 \(a_u\) ,直接将它们“接在”点 \(u\) 之下即可
节点 \(u\) 会留下 \(a_u-t\) 条 待匹配路径
[AGC001C] Shorten Diameter
给定一棵 \(n\) 个点的树,问至少删多少个点使得剩下的树连通,且直径 \(\leq k\)
\(n,\ k\leq2000\)
考虑枚举直径中点,当 \(k\) 是偶数时,我们枚举根 \(rt\) ,则到 \(rt\) 距离大于 \(\frac k2\) 的点需要被删除,找到所需删点数最小的那一个即可; \(k\) 是奇数时同理,枚举一条边作为直径中点即可
时间复杂度 \(O(n^2)\) ,应该可以换根一下做到 \(O(n)\) ,留坑待填
CF878C Tournament
有 \(n\) 个人, \(k\) 项运动,第 \(i\) 个人对第 \(j\) 项运动的经验值为 \(s_{i,\ j}\) , \(s\) 内元素互不相同
你需要恰好举办 \(n-1\) 轮比赛,每一轮比赛由你选择两个人 \(x,\ y\) 和项目 \(p\) ,对项目 \(p\) 经验值较大的人获胜并留下,输的人被淘汰并不能参加比赛
你需要对 \(k=1,\ 2,\ \cdots,\ n\) 求出,仅考虑前 \(k\) 个人时,有多少个人可能留到最后
\(n\leq5\times10^4,\ k\leq10\)
对于两个人 \(i,\ j\) ,若存在 \(p\) 使得 \(s_{i,\ p}>s_{j,\ p}\) ,我们连一条 \(i\to j\) 的有向边,那么答案即为能够到达其余所有点的点的个数。将图缩点后,答案为:入度为 \(0\) 的 SCC 在原图中包含的点的个数
观察一下这张图的性质,可以发现缩点后必定是一条链。假设 SCC \(A\) 能够到达 SCC \(B\) ,那么 \(\forall\ x\in A,\ y\in B,\ t\in[1,\ k],\ \exists\ s_{x,\ t}>s_{y,\ t}\) ,否则它们可以缩成一个 SCC
那么我们用数据结构维护每次加入人后这条链的信息即可
CF878D Magic Breeding
有 \(k\) 个 \(n\) 维向量 \(a_i\) ,有 \(q\) 次操作:
1 x y
,新增一个向量 \(a_t\) ,其中 \(a_{t,\ j}=\max(a_{x,\ j},\ a_{y,\ j})\)2 x y
,新增一个向量 \(a_t\) ,其中 \(a_{t,\ j}=\min(a_{x,\ j},\ a_{y,\ j})\)3 x y
,询问 \(a_{x,\ y}\) 的值\(n,\ q,\ x,\ y\leq10^5\)
\(k\leq12\)
二分 \(a_{x,\ y}\) 的值,将小于 \(a_{x,\ y}\) 的数看作 \(0\) ,否则看作 \(1\)
则 \(\max\) 操作可以看作按位或, \(\min\) 操作可以看作按位与
而所有可能的输入状态(即 \(a_{1\cdots k}\) 在 \(y\) 这一维的取值)只有 \(2^k\) 种,可以暴力枚举
时间复杂度 \(O(n2^k+qk)\)
好像标算做法是 \(\displaystyle O(\frac{q2^k}w)\) 的(
留坑待填
Luogu3537 [POI2012]SZA-Cloakroom
给定 \(n\) 个由三元组 \((a_i,\ b_i,\ c_i)\) 表示的物品,有 \(a_i<b_i\)
有 \(q\) 次询问,每次给出 \(m,\ k,\ s\) ,问能否选出某些物品使得:
- 对于任意被选中的物品 \(i\) ,存在 \(a_i\leq m,\ b_i>m+s\)
- 所有选中的物品的 \(c_i\) 之和为 \(k\)
\(n\leq1000;\ q\leq10^6\)
\(c_i\leq10^3;\ 1\leq a_i<b_i\leq10^9\)
\(k\leq10^5;\ m,\ s\leq10^9\)
想偏了很久……
考虑将物品按 \(a_i\) 升序排序。我们可以求出,仅考虑 \(a_i\) 前 \(x\) 小, \(b_i\) 前 \(y\) 大的物品,它们的 01 背包的状态
这样实际上是很浪费的,考虑记 \(f_{i,\ j}\) 表示,仅考虑 \(a_i\) 前 \(i\) 小的物品,至少要选 \(b_i\) 前 \(f_{i,\ j}\) 大的物品才能凑出 \(j\)
转移显然,时间复杂度 \(O(nk+q)\)
大概就是考虑预处理出任意区间的背包状态,然后发现可以优化()
一道题
有一张空图,要求支持加单向边,询问有多少个点能够到达其余所有点
按时间分治
缩点后,如果有多个入度为 \(0\) 的强连通分量,答案为 \(0\) ,否则答案为 入度为 \(0\) 的强连通分量的点数
有答案的时间是一段后缀
在 \(mid\) 时刻,如果答案非 \(0\) ,向左递归时只用保留入度为 \(0\) 的强连通分量内部的点和边,而向右递归时只用保留强连通分量们和将它们连接起来的边
这样点和边都只会被分到一侧