CF1466G Song of the Sirens
给定由小写字母构成的字符串 (s_0) 和 (t (|t|=n)) ,对于 (1leq i<n, s_{i+1}=s_it_is_i)
有 (q) 次询问,每次给定 (k) 和一个串 (w) ,求出 (w) 在 (s_k) 中的出现次数
模 (10^9+7)
(n, qleq10^5)
(|s_0|leq100; displaystylesum|w|leq10^6)
对于询问,考虑求出对 (s_i (1leq ileq 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(nlog n))
TC13368 OnePointNineNine
给定平面上 (n) 个整点和常数 (D) ,保证任意两点之间的欧几里得距离要么 (leq D) ,要么 (ge1.99 imes D)
求有多少个点集的子集 (S) 满足,对于任意 (x, yin S (x eq y)) ,存在 (dist(x, y)ge1.99 imes D)
答案模 (10^9+7)
(nleq1000)
记 (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)
定义一个集合 (Ssubseteq{1, 2, cdots, n}) 是合法的,当且仅当对于任意 (iin S) ,满足 (jin[1, i), a_imod a_j=0) 的 (j) 都存在于集合 (S)
定义集合 (S) 的权值为 (displaystylesum_{iin S}b_i) ,问最大可能权值
- (nleq3000)
- (a_ileq100)
- (|b_i|leq10^5)
空间限制 32MB
将 “选了 (i) 就必须选 (j) ” 的限制看作一条 (i o j) 的有向边,那么现在即求:给一张带点权的 DAG,选了点 (i) ,则 (i) 的子 DAG 内的点必须被选择,问选择方案的点权和最大值
从最小割的角度考虑
若有限制 (i o j) ,则我们从 (i) 向 (j) 连一条流量为 (inf) 的边,即不能割掉
若 (b_ige 0) ,我们从源点向 (i) 连一条流量为 (b_i) 的边
若 (b_i<0) ,我们从 (i) 向汇点连一条流量为 (b_i) 的边
答案即为 (displaystylesum_{i=1}^nmax(b_i, 0)) 减去 最大流
注意到 (a_i) 值域范围不大,我们在考虑限制 (i o j) 时,继承一下 (lst_i o 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) 个连续段
(1leq aleq4 imes10^4, 1leq bleq10^{18}; nleq10^{12})
考虑对所有取值的二进制表示分别计算其连续段个数,减去相邻取值二进制表示首尾相同的个数
做法一:
(f(x)) 取值的集合可以看作 ({x | xequiv bpmod a}cap[a+b, a imes n+b]capmathbb Z)
考虑数位 dp,用 (xleq a imes n+b) 的答案减去 (x<a+b) 的答案
记 (F_{i, j, k, 0/1, 0/1}) 为,考虑了高 (i) 位,当前数 (equiv jpmod a) ,上一位填的是 (k) ,截至目前是否是前导零,是否卡到上界,满足这些条件的数目前的连续段个数之和
还需要记一个 (G_{i, j, k 0/1, 0/1}) 表示满足这些条件的数的个数,用以辅助转移
如果要卡空间可以写成递推的形式,并使用滚动数组
做法二:
我们考虑第 (i) 位在什么时候会对答案产生 (1) 的贡献
若 (i+1, i) 位形如 (01, 10) 则有贡献,形如 (00, 11) 则没有贡献
然后搞一搞就得到了类欧的形式((
大概可以做到 (log^2)
TC16346 TwoPerLine
在 (n imes n) 的棋盘上放恰好 (k) 个棋子,一个位置至多放一个,每行每列至多放两个,问方案数模 (10^9+7)
(nleq200, 0leq kleq 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) 的点,此时的方案数
那么有 (displaystyleegin{cases}l_0+l_1+l_2=i\l_1+2l_2=jend{cases}) 和 (displaystyleegin{cases}r_0+r_1+r_2=n\r_1+2r_2=jend{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) 对点连了两条边,那么答案为:
其中 (displaystylefrac1{k!}) 去掉连边顺序的贡献, (displaystyleinom{n}{t}^2t!) 是选出 (t) 对点的方案数, (displaystylefrac{inom{m}{2i}(2i)!}{2^i}) 是将这 (2i) 条非法边的可重排列塞到连边序列中的方案数
时间复杂度 (O(n^2k))
GYM101620E [CERC2017]Embedding Enumeration
给定一棵 (n) 个点,以 (1) 为根的树
将其放入一个行数为 (2) 的网格图中,要求:
- (1) 在左上角
- 若有边 ((u, v)) ,则 (u) 在网格图中与 (v) 四相邻
- 两个不同的点不能放在同一个格子中
求方案数。答案模 (10^9+7)
(nleq3 imes10^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) 的下方终止。我们记 (egin{aligned}lst_u=egin{cases}u &( ext{u有零个或两个儿子})\ lst_{son_u} &( ext{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) 个正负号连接而成的表达式,问在其中加入若干对括号所能得到的表达式的值的最大值
(nleq10^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) 会将 (jin S, j eq i) 的新权值 (t_j') 加上 (lfloorfrac{t_i}k floor) ,将 (i) 的新权值 (t_i') 加上 (t_i-(k-1) imeslfloorfrac{t_i}k floor)
注意一次神秘事件并不会影响初始权值 (t_i) ,并且神秘事件的发生是相互独立的
现有 (q) 次操作,有以下三种类型:
1 i j
,将 (f_i) 置为 (j)2 i
,问发生神秘事件后,第 (i) 个点的新权值3
,问发生神秘事件后,所有点新权值中最小值和最大值保证任意时刻不存在长度小于 (3) 的环
- (n, qleq10^5)
- (1leq t_ileq10^{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) 。
(nleq3 imes10^6)
自底向上贪心,对于节点 (u) ,我们已经求出了其每个儿子 (v) ,能延伸出多少条 待匹配路径
记 (u) 所有儿子的 待匹配路径 条数之和为 (s) ,最大值为 (mx)
我们会尽量让 待匹配路径 们在节点 (u) 处匹配,即 将属于不同儿子的两条 待匹配路径 匹配,则匹配个数 (t) 为 (max(0, min(a_u, s-a_u, lfloorfrac s2 floor, s-mx)))
第二项的含义是,若还没拿去匹配的 待匹配路径 个数 (x) 不多于 (a_u) ,直接将它们“接在”点 (u) 之下即可
节点 (u) 会留下 (a_u-t) 条 待匹配路径
[AGC001C] Shorten Diameter
给定一棵 (n) 个点的树,问至少删多少个点使得剩下的树连通,且直径 (leq k)
(n, kleq2000)
考虑枚举直径中点,当 (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) 个人时,有多少个人可能留到最后
(nleq5 imes10^4, kleq10)
对于两个人 (i, j) ,若存在 (p) 使得 (s_{i, p}>s_{j, p}) ,我们连一条 (i o j) 的有向边,那么答案即为能够到达其余所有点的点的个数。将图缩点后,答案为:入度为 (0) 的 SCC 在原图中包含的点的个数
观察一下这张图的性质,可以发现缩点后必定是一条链。假设 SCC (A) 能够到达 SCC (B) ,那么 (forall xin A, yin B, tin[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, yleq10^5)
(kleq12)
二分 (a_{x, y}) 的值,将小于 (a_{x, y}) 的数看作 (0) ,否则看作 (1)
则 (max) 操作可以看作按位或, (min) 操作可以看作按位与
而所有可能的输入状态(即 (a_{1cdots 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_ileq m, b_i>m+s)
- 所有选中的物品的 (c_i) 之和为 (k)
(nleq1000; qleq10^6)
(c_ileq10^3; 1leq a_i<b_ileq10^9)
(kleq10^5; m, sleq10^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) 的强连通分量内部的点和边,而向右递归时只用保留强连通分量们和将它们连接起来的边
这样点和边都只会被分到一侧