Typesetting math: 100%
退役远在天边。|

definieren

园龄:3年粉丝:7关注:4

2024-08-04 09:58阅读: 42评论: 0推荐: 0

2024.8 做题记录

1.有依赖的背包问题

普及组题现在还不会。。。太有实力辣。

2.P6326 Shopping

题目的要求实质上是要我们选的位置构成一个连通块。
可以暴力枚举根做树上依赖背包。
优化的方法是点分治,计算经过当前重心的连通块,不经过的可以地柜计算。
时间复杂度 O(nmlogn)O(nmlogn)

3.P3780 SDOI2017 苹果树

首先这个 thkthk 可以转化为“免费选一条根链,求至多选 kk 个的最大价值”。
考虑枚举这条根链,然后整棵树就被这条链划分成了两部分,且两部分是在 dfs 序上连续的,链上的部分可以选 ai1ai1 个,其余部分可以选 aiai 个。
不放将链上的部分合并到左边的部分,这样就可以预处理两部分的背包,然后 O(k)O(k) 查询答案。
具体来说,在 dfs 的时候,可以先放入 ai1ai1 个,然后递归儿子,合并儿子的时候再把儿子中少选的一个加上,这样算的就是对的。

时间复杂度 O(nk)O(nk)

4.P3571 POI2014 SUP-Supercomputer

先将操作转化为每次最多删 kk 个叶子。
不难发现当叶子个数 kk 的时候答案就是树高 hh
当叶子数大于 kk 的时候,我们贪心地选深度最大的叶子删掉。
如果记 cnthcnth 表示深度大于 hh 的点数,那么答案可以表示为 maxh{h+cnthk}maxh{h+cnthk},证明可以看题解。
推一下式子:

ansk=maxh{h+cnthk}=maxh{h+cnthk}ansk=maxh{h+cnthk}=maxh{h+cnthk}

里面这个是若干个一次函数的最大值,考虑类似斜率优化的方式推式子:

ansk=h+cnthkh=cnth1k+anskansk=h+cnthkh=cnth1k+ansk

这就是说:有一些点 (cnth,h)(cnth,h),你要用斜率为 1k1k 的直线去切它,要截距最大。
维护上凸壳,斜率是单调的,所以扫一遍就行。

时间复杂度 O(n)O(n)

5.P4383 八省联考 2018 林克卡特树

题意可转化为:选出恰好 kk 条链,使得权值和最大。
首先我们有暴力 DP:设 fu,i,0/1/2fu,i,0/1/2 表示以点 uu 为根的子树中选恰好 ii 条链,点 uu 的度数为 0 / 1 / 2 的最大权值。
转移就是分类讨论一下 (u,v)(u,v) 这条边选不选,做一个树上背包,较为繁琐。
时间复杂度 O(nk)O(nk)

感觉一下没有什么阳间的优化方式,而且看到到“恰好”,考虑凸优化。
如果设 f(k)f(k) 表示选择恰好 kk 条边的最大权值,通过打表等方式可以发现它是凸的(具体证明见 https://www.luogu.com.cn/article/hkdxyitj)。
于是套个 WQS 二分就做完了。

时间复杂度 O(nlogn)O(nlogn)

6.P5298 PKUWC2018 Minimax

fu,ifu,i 表示点 uu 权值为第 ii 大的数的概率,转移为:

fu,ipu×(flsu,i×jifrsu,j+frsu,i×j<iflsu,j)+(1pu)×(flsu,i×jifrsu,j+frsu,i×j>iflsu,j)fu,ipu×(flsu,i×jifrsu,j+frsu,i×j<iflsu,j)+(1pu)×(flsu,i×jifrsu,j+frsu,i×j>iflsu,j)

然后线段树合并即可。
时间复杂度 O(nlogn)O(nlogn)

7.Minecraft

fi,jfi,j 表示考虑完了从低往高的第 ii 位,进位为 jj 是否可行。
转移是平凡的。
输出方案的话同时记录一下转移即可。
时间复杂度 O(nk)O(nk)

8.P4590 TJOI2018 游园会

首先考虑计算 LCS,这个可以通过 DP 简单实现。
考虑 DP 套 DP,先把内层的 DP 变成自动机。
考虑如何压缩节点数,不难发现 DP 数组单调不减且差分数组只有 0 和 1,所以可以只存差分数组。

剩下的 DP 就是简单的了,设 fi,j,0/1/2fi,j,0/1/2 表示确定了 ii 个字符,匹配了 0 / 1 / 2 个字符的方案数。
转移是简单的。时间复杂度 O(nk2k)O(nk2k)

9.P5279 ZJOI2019 麻将

首先考虑如何判定一些牌是不是胡的:设 dpi,j,k0/1dpi,j,k0/1 表示考虑了前 ii 中牌,预留了形如 (i1,i,i+1)(i1,i,i+1)jj 个,预留了形如 (i,i+1,i+2)(i,i+1,i+2)kk 个,是否预留对子的方案数。
转移已是简单的,对于划分成 7 个对子的形式可以记一个 cntcnt 表示能取出的对子的数量然后简单判断。

先对原问题进行一个简单的转换:对于每种方案算胡的轮数之和 等于 算第 ii 轮还没胡的方案数之和。
考虑把上面的 DP 变成自动机然后在自动机上 DP。
先压缩状态:首先有 j,k2j,k2,因为如果等于 3 就可以直接凑成 3 个刻子,然后我们钦定 DP 值是 44 的。
这样状态就变成了 2091 个。

再考虑 DP:设 fi,j,kfi,j,k 表示考虑了前 ii 种牌,摸了 jj 张,在自动机上状态为 kk 的方案数。
转移是简单的。

时间复杂度 O(n2S)O(n2S),其中 S=2091S=2091

10.P8497 NOI2022 移除石子

先考虑判定:设 dpi,j,kdpi,j,k 表示考虑了前 ii 个位置的石子,至少扩展到 ii 的操作 2 有 jj 个,至少扩展到 i+1i+1ii 操作有 kk 个的是否可行,转移就是考虑 ii 位置开始了多少个操作 2。

要求计数,考虑将判定的 DP 变成自动机后在自动机上 DP。
先压状态数,不难通过看题解发现 j,k2j,k2,这样状态数就是 87658765 的了。

通过讨论可以发现,除了 “k=1k=1ai=0ai=0” 和 “k=1,n=3,a1=a2=a3=1k=1,n=3,a1=a2=a3=1” 的情况,若 k1k1 有解, kk 一定有解。
所以上面的 DP 可以将 “是否可行” 改为 “最少加几个石子”。

然后可以 DP:设 fi,jfi,j 表示考虑了前 ii 个位置,位于自动机的节点 jj 上的方案数。
对于 ai8ai8 的情况是与 ai=8ai=8 相同的。
直接转移即可。

时间复杂度 O(nS)O(nS),其中 S=8765S=8765

11.Range Minimum Sum

放到笛卡尔树上考虑,首先一个点都不删的答案是好求的:

sum=uau×sizelsu×sizersusum=uau×sizelsu×sizersu

考虑删掉一个点后的影响:

  • 对于祖先节点,影响可以一遍 Dfs 求出。
  • 对于儿子节点,他们子树内部的贡献是不变的。但是左右儿子要合并起来。发现合并的是左儿子的右链,右儿子的左链,所以暴力归并算贡献即可。

时间复杂度 O(n)O(n)

12.Heartbeat

首先 nn 的位置把整个序列分成了两部分,左边的部分只有前缀最大值,右边的部分只有前缀最小值,两边的计算是类似的。
首先我们算出 fi,j,kfi,j,k 表示 ii 个元素的排列,有 jj 个前缀最大值、kk 个上升位置的方案数。
考虑如何转移。这种一般是考虑插一个元素。这里如果是插最大值的话,全局最大值的个数会减少。所以我们考虑插最小值:

  • 最小值插到开头:fi,j,kfi+1,j+1,k+1fi,j,kfi+1,j+1,k+1
  • 最小值插到结尾:fi,j,kfi+1,j,kfi,j,kfi+1,j,k
  • 最小值插到上升的间隙中:fi,j,k×kfi+1,j,kfi,j,k×kfi+1,j,k
  • 最小值插到下降的间隙中:fi,j,k×(i1k)fi+1,j,k+1fi,j,k×(i1k)fi+1,j,k+1

然后记 Li,jLi,j 表示 ii 个元素有 jj 个上升位置时前缀最大值的贡献,Ri,jRi,j 表示 ii 个元素有 jj 个上升位置时后缀最小值的贡献,这两个数组都能通过 ff 数组计算出来:

Li,kfi,j,k×aj+1Ri,i1kfi,j,k×bj+1Li,kfi,j,k×aj+1Ri,i1kfi,j,k×bj+1

右式中 jj 加了 1 是因为要加上 nn 的贡献。

ansi,jansi,j 表示 长度为 ii 的排列有 kk 个上升位置时前缀最大值和后缀最小值的贡献。
ansans 可通过 L,RL,R 计算出:

(i+ui)Li,j×Ru,vansi+u+1,j+v+[i>0](i+ui)Li,j×Ru,vansi+u+1,j+v+[i>0]

这是个二维卷积的形式,先改写一下:

Li,ji!×Ru,vu!ansi+u+1,j+v(i+u)!Li,ji!×Ru,vu!ansi+u+1,j+v(i+u)!

ansans 中第二维的 +[i>0]+[i>0] 可以通过对 LL 提前处理消掉。
这个直接做是 O(n4)O(n4) 的。

之后有两种处理方法。

sol1

这里我们相当于做了 O(n2)O(n2)O(n2)O(n2) 的多项式乘法,可以通过转成点值变成 O(n2)O(n2)O(n)O(n) 的点乘,这样时间复杂度就是 O(n3)O(n3) 的了,不难注意到 ansansn1n1 次多项式。

算完点值以后直接拉插插出每项系数即可。

时间复杂度 O(n3)O(n3)

sol2

直接看官方做法把。

13.P8349 SDOI/SXOI2022 整数序列

调不出来了 /ll

首先对出现次数根号分治,记阈值为 BB
对于两个小块,可以把有用的位置拉出来暴力,时间复杂度 O(qB)O(qB)
对于两个大块,可以暴力然后记忆化,时间复杂度 O(n2B)O(n2B)
对于一个大块和一个小块,离线处理。对于每个小块元素的连续段,可以找出他前后的连续段长度个大块元素,不难发现只有这些事有用的,然后暴力即可。时间复杂度 O(qB)O(qB)

平衡一下,时间复杂度为 O(nq)O(nq)

14.P5047 Ynoi2019 模拟赛 Yuno loves sqrt technology II

首先有朴素的莫队 O(nmlogn)O(nmlogn) 做法。

先研究右端点的移动。
记端点从 (l,r1)(l,r1) 移动到 (l,r)(l,r) 的影响为 f(l,r,r)f(l,r,r) 表示 (l,r1)(l,r1) 中比 arar大的数的个数。
发现贡献有可差分性,不妨将他变为 f(1,r,r)f(1,l1,r)f(1,r,r)f(1,l1,r),分别去做。
首先 f(1,r,r)f(1,r,r) 这个是好解决的,只有 O(n)O(n) 种本质不同的询问,可以扫描线树状数组求出,时间复杂度 O(nlogn)O(nlogn)
对于 f(1,i,j)f(1,i,j) 这类贡献,不难发现只有 O(nm)O(nm) 个(端点移动次数),所以对 ii 这一维扫描线,每次查询大于 ajaj 的数的个数。这部分有 O(n)O(n) 次单点改,O(nm)O(nm) 次前缀查,可以根号平衡。

但发现空间不够,原因在于第二类贡献有 O(nm)O(nm) 个。
但是我们发现,左端点相同时右端点的移动是一段区间,且只有 O(m)O(m) 个,所以直接存区间就行了。

这样就做到了时间复杂度 O(nm)O(nm),空间复杂度 O(n+m)O(n+m)

15.AtCoder Beginner Contest 366

https://www.cnblogs.com/definieren/p/18353652

16.Codeforces Round 965 (Div. 2)

https://www.cnblogs.com/definieren/p/18353122

17.AtCoder Regular Contest 182

https://www.cnblogs.com/definieren/p/18354900

18.EPIC Institute of Technology Round August 2024 (Div. 1 + Div. 2)

https://www.cnblogs.com/definieren/p/18361339

19.Museums Tour

建分层图,缩点,然后 DP。
时间复杂度 O(nd)O(nd)

20.D. Perishable Roads

注意到关键应该是最短的边。
发现答案的树的形态应该是形如:根和最短的边有一条链连接,最短的边下挂着个菊花。
现在的关键是找这一条链。
发现如果链上的边依次是 e1,e2,,eme1,e2,,em,则 i<m1,ei>ei+1i<m1,ei>ei+1
因为如果存在 eiei+1eiei+1,那么我们可以把 ei+1ei+1 换成任意一条连向最短边的路径,这样答案会更优。
对于最后一条边,如果 em1>emem1>em,那么它的贡献是 emem,否则是 em1em1
现在我们的答案是 iei+min edge×(n1m)iei+min edge×(n1m),把 mm 放到前面的求和里,得到:

ans=i(eimin edge)+min edge×(n1)ans=i(eimin edge)+min edge×(n1)

这样根据刚才的分析,先将每条边的边权减去 min edgemin edge,将每个点的初值赋成 2minjwi,j2minjwi,j 然后跑最短路即可。
时间复杂度 o(n2)o(n2)

21.P1402 酒店之王

简单题。拆一下点随便连就行。

22.F. Special Edges

卡不过去,就当过了把 /ng
最大流等于最小割,所以 O(2k)O(2k) 枚举把这 kk 条边选与不选的最小割都求出,然后询问时拼一下即可。

23.I. Marbles

无源汇上下界可行流。
1 操作就把新建点,连 [0,n][0,n] 的边。
2 操作就向起始点连 [0,1][0,1] 的边。
3 操作就新建一个点连 [l,r][l,r] 的边。
最后再向初始点连一边即可。

24.E. ALT

建模是简单的:源点向每条路径连流量为 1 的边,路径向每个点连流量为 ++ 的边,每个点向汇点连流量为 11 的边,这样最小割即为答案。
边数太多,考虑优化建图。
有以下几种方式:倍增、树剖加线段树等。
然后就做完了。

25.F. Making It Bipartite

首先如果 aiaiajaj 的因数,就连一条 ijij 的边。
发现问题等价于删多少个点是的最长链不超过 2。
这个是切糕,做完了。

26.P3227 HNOI2013 切糕

典题。

27.P6054 RC-02 开门大吉

和切糕一样,注意边要连全。

28.P4248 AHOI2013 差异

建出 SA 后统计每个 htihti 作为区间最小值的出现次数。

29.P2178 NOI2015 品酒大会

建 SA,然后在 htht 数组的笛卡尔树上统计答案。

30.P2408 不同子串个数

31.P1117 NOI2016 优秀的拆分

求出 fifi 表示以 ii 结尾的 AAAA 的数量,gigi 表示以 ii 开头的 AAAA 的数量,则:

ans=ifi×gi+1ans=ifi×gi+1

现在的问题是求 ffgg,我们只关注求 ff 因为求 gg 和把 ss 翻转后求 ff 是等价的。

考虑枚举 AAAAAA 的长度 lenlen,并以之为间隔做标记。
我们依次考虑相邻两个标记之间的能作为 AAAA 的两个 AA 之间的间隙的位置的数量。
分别求一和正向和反向的 lcplcp,它们的交即为答案。
细节可能比较多。时间复杂度 O(nlogn)O(nlogn)

32.P3181 HAOI2016 找相同字符

先建两个串拼起来建 SA,然后答案是两个串各选一个位置 LCP 的和,笛卡尔树上算一算就行。

33.P3804 【模板】后缀自动机(SAM)

/fendou

34.E. Cool Slogans

首先发现如果对于相邻的两个选的串,可以将他们没有互相匹配的后缀删掉,这样就得到了 sisi 一定是 si+1si+1 的后缀。
建出 SAM,在 parent 树上自上而下 DP。
fifi 表示当前在 ii 节点最长的序列长度,gigi 表示在长为 fifi 时最后一个元素的最小节点。
线段树维护 endposendpos 集合后转移是简单的。

35.P4770 NOI2018 你的名字

先考虑 l=1,r=|S|l=1,r=|S|
SSTT 分别建 SAM。
对于 TT 的每个前缀的所有后缀,满足在 SS 中没出现过的的一定一段前缀。
所以考虑枚举 TT 的每个前缀,维护当前在 SS 上匹配的点和匹配长度,每次前缀长度 +1 时能匹配则匹配,否则暴力跳父亲即可得到每个前缀的最长的没有在 SS 中出现的后缀的长度。
最后对于每个在 SS 中出现的前缀的后缀,将它的后缀全部设为出现过然后在 SAM 上统计答案即可。

再考虑一般的情况。
第一个问题我们不能暴力跳父亲了,因为 SS 只保留了 [l,r][l,r] 的区间,所以一个节点上的 endposendpos 集合不一定相同。正确的做法是维护匹配长度 lenlen,不能匹配则将 lenlen 减一后再尝试匹配,若 lenlen 已经小于 minlenpminlenp,那么就跳父亲。
第二个要解决的问题是我们无法判断能不能走转移边。这个可以线段树合并维护 endposendpos 集合后简单判断。
其余部分与 l=1,r=|S|l=1,r=|S| 的情况基本一致。

时间复杂度 O((|S|+|T|)log|S|)O((|S|+|T|)log|S|)

36.P6139 【模板】广义后缀自动机(广义 SAM)

/fendou

37.P4482 BJWC2018 Border 的四种求法

可以用基本子串字典做到 O(nlogn)O(nlogn),但是我在练 SAM。

问题等价于找一个 pos[l,r]pos[l,r],满足 lcs(pos,r)posl+1lcs(pos,r)posl+1
建 SAM,求 lcslcs 就可转化为两点的 lcalca

考虑离线下来倒着扫 i:n1i:n1,同时维护一个未解决的询问的集合,每次将还没有被解决的询问中答案为 ii 的询问删掉,然后将右端点为 ii 的询问加入集合中。
这样只要我们支持每次 O((1+应被删除的询问个数)polylog(n))O((1+)polylog(n)) 地将应被删除的询问删除,O(polylog(n))O(polylog(n)) 地将每个询问加入,时间复杂度就是对的。

先考虑怎么暴力做。就是不断跳父亲(枚举 lcalca),每次将子树每的询问 check 一遍。
考虑树剖优化这个过程,模拟树剖求 lcalca 的过程。
每次加入询问的时候,跳重链,并把询问挂到每次跳到的点上。
尝试用 ii 删除询问的时候,ii 不断跳重链。不妨设在同一条重链上,ii 跳到的点是 uu,询问的点跳到的点是 vv,对他们的深度分类讨论一下:

Case1: depudepvdepudepv

这也就是说 lca=vlca=v,此时应有:

lenvil+1lenv+li+1lenvil+1lenv+li+1

线段树叶子处开个 set 维护 lenv+llenv+l 的最大值和询问编号即可。

Case2: depu<depvdepu<depv

这也就是说 lca=ulca=u,此时应有:

lenuil+1lenui1llenuil+1lenui1l

线段树叶子处开个 set 维护 1l1l 的最小值和询问编号即可。

删除一个询问可以使用标记懒惰删除。
这样我们就做到了均摊 O((n+q)log2n)O((n+q)log2n)
为什么我写了 9K + /tuu

38.P8150 再会 | Sayounara

根本想不到 /ll

找到最小值位置后就能通过 O(n)O(n) 次操作得出答案,所以目标是找最小值。
考虑三分,拿一个 vector 存当前的分治区间,记其为 [l,r)[l,r),记两个三等分点分别为 p1,p2p1,p2
此时区间被分成 [l,p1)[l,p1)[p1,p2)[p1,p2)[p2,r)[p2,r)

每次通过询问得到:x=query(l,p21)query(l,p11),y=query(p1,r1)query(p2,r1)x=query(l,p21)query(l,p11),y=query(p1,r1)query(p2,r1)
也即:x=mini[l,p2)aimini[p1,p2)ai,y=mini[p1,r)aimini[p2,r)aix=mini[l,p2)aimini[p1,p2)ai,y=mini[p1,r)aimini[p2,r)ai

通过细致的分类讨论可以得出最小值在哪个区间中,这样就可以以 O(logn)O(logn) 的代价求出最小值。

39.D - 軍艦ゲーム

fu,ifu,i 表示在点 uu,生命值为 ii 走到 nn 的期望步数。
转移为:

fu,imin{f1,H+Hi,(u,v)Efv,idvdegu+1}fu,imin{f1,H+Hi,(u,v)Efv,idvdegu+1}

发现唯一使转移有后效性的元素是 fi,Hfi,H,考虑对它动一些手脚。
二分 f1,Hf1,H 的值 AA,然后按上面的转移,得出新的 f1,Hf1,H 的值 g(A)g(A),然后调整二分的上下界。
不难通过归纳证明 g(A)1g(A)1,也就是说 (g(A)A)0(g(A)A)0,也就是说有单调性,可以二分。

时间复杂度 O(nhlog1ϵ)O(nhlog1ϵ)

40.P9144 THUPC 2023 初赛 最后的活动

首先显然可以爆搜+迭代,然后把迭代换成上一个题的二分就对了。
时间复杂度 O(2nmlog1ϵ)O(2nmlog1ϵ)

41.P9073 WC/CTS2023 楼梯

自然可以想到维护右下的轮廓线,1 表示向下的边,0 表示向左的边,现在的目的是找到一个形如 0...1 的子串,使得它的长度为 q+1q+1
前三个操作可以平衡树简单维护,现在要做的就是查询。
考虑把 i1(modq)i1(modq) 的位置 ii 单独拉出来,因为第一个位置一定是 1,最后一个位置一定为 0,所以除非楼梯是空的,一定可以找到相邻的两个位置使得他们为 10。
考虑一个类似二分的东西,每次找到 midmid,如果 midmid 位置是 0,就向左逼近,否则向右逼近,这样就会一直满足条件。
时间复杂度 O(nlognlogV)O(nlognlogV)

42.P5319 BJOI2019 奥术神杖

卡精度。。。懒得喷。
感觉不被关键词提示的话做不出来。
首先肯定要对咒语建 AC 自动机然后跑 DP 啥的。
先取个 lnln,然后可以化成分数规划的形式,DP 就好了。
时间复杂度 O(nslog(ϵ1V))O(nslog(ϵ1V))

43.Chips on a Board

自己想了个很蠢的莫队+trie。。。关键词提示后才会 O(nlogn)O(nlogn)
这显然和 Nim 游戏是一样的,所以要求的就是区间到左端点距离的异或和。
考虑倍增维护,每次倍增的时候加上最高位的贡献即可。
时间复杂度 O(nlogn)O(nlogn)

44.CF1523H Hopping Around the Array

跳的时候一定是跳到 ai+iai+i 最大的位置,我们称其为跳一步。
一眼倍增。设 fi,j,kfi,j,k 表示从 ii 开始跳,跳了 2j2j 步,删了 kk 个数跳到的位置和再跳一步能跳到的范围。
然后倍增即可,时间复杂度 O(nk2logn)O(nk2logn)

45.P6406 COCI2014-2015#2 Norma

扫描线线段树,信息和标记随便设计一下就好。
时间复杂度 O(nlogn)O(nlogn)

46.P3350 ZJOI2016 旅行者

分治最短路板子。

47.CFgym103409H Popcount Words

首先的思路是将询问串建 AC 自动机,然后将原串的每个前缀所在的点打上标记,答案为子树和。
现在的问题是如何将原串的每个前缀所在的点打上标记。

我们不妨设这个 popcount 串是从 0 开始的。
分析一下发现可以通过如下的方式递归构造出来:

  • 初始 s=0s=0
  • rev(s)rev(s) 表示将 ss 按位取反后得到的字符串,那么有:s=s+rev(s)s=s+rev(s)

这看着就很倍增!记 fi,j,kfi,j,k 表示从节点 ii 开始匹配 s[k2j,(k+1)2j+11)s[k2j,(k+1)2j+11),匹配完后能到哪个点,其中 k{0,1}k{0,1},这个可以通过下面的式子简单预处理:

fi,j,kffi,j1,k,j1,1kfi,j,kffi,j1,k,j1,1k

现在考虑怎么用 O(logn)O(logn)ff 把区间 [l,r][l,r] 凑出来。
考虑用形如 [2i,2i+1)[2i,2i+1) 这样的区间把 [l,r][l,r] 拼起来,现在的问题就是如何知道它们是否翻转,这个可以直接判断 parity(l)parity(l)
这样我们就实现了把 [l,r][l,r]O(logn)O(logn) 个区间拼起来。

现在的问题是确定每个位置被经过了多少次。记 gu,j,kgu,j,k 表示从点 uu 开始匹配 s[k2j,(k+1)2j+11)s[k2j,(k+1)2j+11) 所经过的点被匹配的次数,初始值可以通过刚才的倍增得到。
现在考虑怎么下传经过次数,就是将 jj 的出现次数更新到 j1j1 上去。
这部分是简单的:

gu,j,kgu,j1,kgu,j,kgfu,j1,k,j1,1kgu,j,kgu,j1,kgu,j,kgfu,j1,k,j1,1k

最后一个点的经过次数就是 gu,0,0+gu,0,1gu,0,0+gu,0,1,统计即可。
时间复杂度 O((n+|s|)logV)O((n+|s|)logV)

48.ARC150F Constant Sum Subsequence

首先的思路是设 fifi 表示凑出 sum=isum=i 的序列的最短前缀。
如果记 pre(i,x)pre(i,x) 表示 ii 前面最大的 jj 满足 aj=xaj=xsuf(i,x)suf(i,x) 表示 ii 后面最小的 jj 满足 aj=xaj=x,那么转移为:

fimaxj<isuf(fj,ij)fimaxj<isuf(fj,ij)

现在的问题是优化这个转移。
有一个重要但是比较显然的观察:fifi 单调不降。
考虑通过分治的方式来寻找最优决策点。
现在的分治区间是 [l,mid][l,mid],我们已经知道了 [l,mid][l,mid] 的 DP 值,现在的问题是如何用他们更新 [mid+1,r][mid+1,r] 的 DP 值。
枚举在后面添加的数 ii,发现我们可以按 ii 的序列中的出现位置把 f[l,mid]f[l,mid] 分成若干段,且对于相邻的两段 [l1,r1][l1,r1][l2,r2][l2,r2],有 j[l1,r1],suf(fj,i)<l2j[l1,r1],suf(fj,i)<l2
所以根据前面的单调性,只有最后一段是有用的,找出这一段的最前面的 ff 更新即可。

时间复杂度 O(SlogSlogn)O(SlogSlogn)

49.P8231 AGM 2022 资格赛 农场

整体二分,时间复杂度 O((n+q)lognlogT)O((n+q)lognlogT)

50.CF1217F Forced Online Queries Problem

强制在线和没有没啥区别,直接线段树分治。

51.CF833D Red-Black Cobweb

显然要点分治。
考虑当前有两条根链,他们权值分别为 (c0,c1,prod)(c0,c1,prod)(c0,c1,prod)(c0,c1,prod),其中 c0c0 表示白边条数,c1c1 表示黑边条数,prodprod 表示边权乘积,prod×prodprod×prod 能贡献到答案当且仅当:

{2(c0+c0)c1+c1c0+c02(c1+c1){2(c0+c0)c1+c1c0+c02(c1+c1)

移项可得:

{2c0c1c12c0c02c12c1c0{2c0c1c12c0c02c12c1c0

发现至少满足一个,所以用满足第一个的除以不满足第二个的即可。
时间复杂度 O(nlog2n)O(nlog2n)

52.P4886 快递员

先随便取一个点当根,然后计算出答案,并将取到最大距离的点对存下来。

考虑什么时候向子树走能不能减小答案:

  • 存在一个最大的点对跨过当前钦定的根。
  • 存在两个不同的商品在不同的子树内。

发现除了这两种情况,能走的子树是固定的。
所以类似点分治,每次走到对应子树的重心即可。
时间复杂度 O(mlogn)O(mlogn)

53.P8907 USACO22DEC Making Friends P

考虑一个延时连边,就是每次我们把 uu 的连向的点连成完全图时,我们只将其中编号最小的点向其他点连边,其他的边会再后面一起连。

直接做是 O(n2)O(n2),启发式合并即可做到 O(nlog2n)O(nlog2n)

54.CF566C Logistical Questions

不妨记 f(u)=nv=1Distance(v,u)32wvf(u)=nv=1Distance(v,u)32wv 表示以 uu 为根时的答案。不难发现,随着 uu 距离真正的带权重心的减少,ff 也是在不断变小的。

考虑通过类似点分治的方式找出带权重心。

首先钦定一个点当根,现在我们要知道的是真正的的带权重心在哪个儿子的子树中。根据上面的结论,至多存在一个儿子满足 f(v)<f(u)f(v)<f(u),这个儿子就是我们要选的点。

考虑记 Δ(v)Δ(v) 表示向 vv 的子树走 ϵϵ 的距离后 ff 的变化量。根据求导可得:

Δ(v)=xSubtree(u)32wxDistance(u,x)Δ(v)=xSubtree(u)32wxDistance(u,x)

这个可以暴力算出,然后挑选能让答案减少的子树走即可。

时间复杂度 O(nlogn)O(nlogn)

55.CF715C Digit Tree

直接点分治,两端拼起来的时候要判 v1×10len2+v20(modM)v1×10len2+v20(modM),这个可以把同类的放到一起变成 v1+v2×10len20(modM)v1+v2×10len20(modM)。求逆元要用扩欧。

时间复杂度 O(nlogn)O(nlogn)

56.CF471D MUH and Cube Walls

在差分数组上 KMP。

57.CF1344E Train Tracks

考虑对于每个点,如果它在时刻 x1,x2,xkx1,x2,xk 改变了方向,那么就相当于我们要在 (0,x1],(x1,x2],,(xk1,xk](0,x1],(x1,x2],,(xk1,xk]kk段时间中都操作一次。

如果我们能对每个点分别求出这些区间,问题就变成了:

有一个无限长的序列,你要给每个位置 ii 填一个 [0,k][0,k] 的数 aiai,满足 i[1,k],j[li,ri],aj=ii[1,k],j[li,ri],aj=i

这个是经典贪心,按左端点排序,维护当前的右端点集合,每次贪心地满足最小的右端点的限制即可。

考虑怎么找这 kk 个区间。仔细观察,发现初始的时候树被剖成了若干条链,每次操作其实就是把 uu 的根链拉出来。
发现这其实就是 LCT 的 access,所以直接 LCT 维护即可,kkO(mlogn)O(mlogn) 级别的。
有一点小细节,就是你点 uu 在 access 的时候不应该把它原本指向儿子的边切掉。
时间复杂度 O(mlog2n)O(mlog2n)

58.P8528 Ynoi2003 铃原露露

重点在于支配对的构造。

先考虑一组 (u,v,z)(u,v,z) 对答案的影响:

  • au<az<avau<az<av:对答案无影响。
  • az<au<avaz<au<av:ban 掉 l(az,au],r[av,n]l(az,au],r[av,n](l,r)(l,r)
  • au<av<azau<av<az:ban 掉 l[1,au],r[av,az)l[1,au],r[av,az)(l,r)(l,r)

考虑对于一个 z=lca(u1,v1)=lca(u2,v2)z=lca(u1,v1)=lca(u2,v2),如果有 [u2,v2][u1,v1][u2,v2][u1,v1],那么 (u2,v2,z)(u2,v2,z) 这个三元组是无用的。
也就是说,如果我们固定了 lcalca,那么对于一个点 uu,它一定只会选在其他子树中它的前驱和后继形成支配对。
如果我们在启发式合并的过程中做这个东西,不难发现有用的支配对只有 O(nlogn)O(nlogn) 个。

现在的问题是已知 o(nlogn)o(nlogn) 个支配对,如何算答案。
把点放到二维平面上,问题就变为矩形加,矩形查 0 的个数。
可以扫描线、区间加历史和线段树维护,时间复杂度 O(nlog2n)O(nlog2n)

59.P9678 ICPC2022 Jinan R Tree Distance and P9058 Ynoi2004 rpmtdq

如果对于 (u1,v1)(u1,v1)(u2,v2)(u2,v2) 满足 u2u1<v1v2u2u1<v1v2Distance(u1,v1)Distance(u2,v2)Distance(u1,v1)Distance(u2,v2),那么 (u2,v2)(u2,v2) 肯定不会对答案产生贡献。此时我们称 (u1,v1)(u1,v1) 支配了 (u2,v2)(u2,v2)
考虑怎么构造支配对。因为是路径信息,考虑点分治构造。

现在问题变为有若干二元组 (u,depu)(u,depu),称 (u1,v1)(u1,v1) 支配了 (u2,v2)(u2,v2) 当且仅当 u2u1<v1v2u2u1<v1v2depu1+depv1depu2+depv2depu1+depv1depu2+depv2,要找出尽量少的支配对。
仔细思考一下,上面那个条件等价于说 depudepudepvdepv[u,v][u,v] 中的最小、次小值。
枚举 uu,钦定 uu 是最小值我不会做,但是我会做钦定 uu 是次小值,此时的 vv 一定是 maxdepvdepuv<uvmaxdepvdepuv<uvmindepvdepuv>uvmindepvdepuv>uv

这也就是说,对于在一次分治中,每个点只会主动产生 2 个支配对,所以支配对个数是 O(nlogn)O(nlogn) 的。
查询就是矩形查 maxmax,扫描线即可。
时间复杂度 O(nlog2n)O(nlog2n)

60.P5291 十二省联考 2019 希望

首先的第一想法是把包括每个点的答案算出来然后相加对吧,但这样会算重。
但是你发现,对于一组方案, 它能到达的点一定是一个连通块,我们想让它只被算一次。这个可以点边容斥 1=VE1=VE

也就是说,我们要把每个点和每条边的答案算出来相减。
考虑 DP:记 fu,ifu,i 表示选出一个在 uu 子树内且最远点与 uu 距离不超过 ii 的包含 uu 的连通块方案数,gu,igu,i 表示选出一个在 uu 子树内且最远点与 uu 距离不超过 ii 的包含 uu 的连通块的方案数。
转移为:

fu,ivson(u)(1+fv,i1)gu,igfau,i1vson(fau)vu(fv,i2+1)+1fu,ivson(u)(1+fv,i1)gu,igfau,i1vson(fau)vu(fv,i2+1)+1

然后点的贡献为 (fu,Lgu,L)k(fu,Lgu,L)kufauufau 这条边的贡献为 (fu,L1(gu,L1))k(fu,L1(gu,L1))k

后面的以后再说 /ng

61.P8543 「Wdoi-2」纯粹的复仇女神

考虑每个元素的贡献。
对于 aiai,记以颜色和它相同的以它为最小值的极长区间为 [Li,Ri][Li,Ri],那么它就会对 l[Li,i]r[i,Ri]l[Li,i]r[i,Ri] 的询问产生 aiai 的贡献。

所以问题等价于矩形 chkmax,单点查,扫描线线段树标记永久化 multiset 维护即可。
时间复杂度 O(nlog2n+qlogn)O(nlog2n+qlogn)

62.CF506D Mr. Kitayuta's Colorful Graph

暴力是枚举每种颜色,并查集,然后枚举每个询问进行查询。
我们把询问 (u,v)(u,v) 挂到被询问次数较少的一个点上,并去重,这样每个点只会被挂 O(q)O(q) 个询问(原理同三元环计数),然后暴力即可。

时间复杂度 O(mq)O(mq)

63.P9149 串串题

首先发现,bb 中的元素是一定不能删的,因为删掉以后一定不匹配。
考虑只保留 bb 中的元素 KMP 一遍,一次计算每个匹配的位置的贡献。

对于一个匹配区间 (l,r)(l,r),记其中不在 bb 中的元素个数为 tt,所有不在 bb 中的元素个数为 WW,那么它的贡献为 (Wtdt)(Wtdt)
时间复杂度线性。

64.P9196 JOI Open 2016 销售基因链

首先正反建 Trie,然后问题就变为了两棵子树求交,这个是 dfn 上二维数点。
时间复杂度 O(|S|log|S|)O(|S|log|S|)

posted @   definieren  阅读(42)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起