DS 合集

Problem A. P5314 [Ynoi2011] ODT

题意:

给定一棵树,树有点权,要求支持路径加,查询一个点的距离小于等于 1 的邻域的 k 小点权。

1n,m1063 秒,500 MB。

解法:

小清新树剖题。

对于这类看似无从下手的树上问题,考虑树剖可能是一个很好的手段。

先将路径加改为到根路径加,树剖的很好性质是到根路径总会被分为 O(logn) 条重链。于是一个自然的想法就出来了。对于每个点使用平衡树维护除了其重儿子和父亲外的点权。询问时重新插入即可。现在到根路径加只需要在轻重链改变时重构一下。同时要维护路径加单点求值,用树状数组维护即可。总复杂度 O(nlog2n),可以通过。

Submission Link.

Problem B. P5311 [Ynoi2011] 成都七中

题意:

给你一棵 n 个节点的树,每个节点有一种颜色,有 m 次查询操作。

查询操作给定参数 l r x,需输出:

将树中编号在 [l,r] 内的所有节点保留,x 所在连通块中颜色种类数。

每次查询操作独立。

1n,m,col105lxr。时限 1 秒。

解法:

好题。

考虑 x 所在连通块的点,其充要条件为到 x 的路径上的点的最小值和最大值都在 [l,r] 内。

这里有一个很显然的东西,设对 l,r,x 询问答案为 f(l,r,x),我们发现对于任意一个和 x 连通的 y,都有 f(l,r,x)=f(l,r,y),如果我们能方便的找到某个 y,且这个 y 的答案便于计算,那就好办了。

统计关于一个端点为 x 的路径时,一个套路是在点分树上考虑。发现我们如果找到最浅的 x 在点分树上的祖先 y,使得 yx 是连通的,那么连通块其余点必然在点分树中 y 子树内。这个性质并不十分显然。如果存在某个 y 子树外的点和 x 连通,那么 x 必然和 x,y 在点分树上 LCA 连通,这个 LCA 必然在 y 之上,和 y 的最浅性不符。

对于每个询问找到 y,之后的事情就容易了。将询问挂到 y 上面,然后对于每个 y,对 y 子树内的点到 y 的路径的最小值和最大值统计答案,只需要简单的扫描线。总复杂度 O(nlog2n),可以通过。

Submission Link.

Problem C. P7126 [Ynoi2008] rdCcot

题意:

给定一棵 n 个点的树,无边权。再给定一个常数 C,构造一个 n 个点的无向图,(u,v) 连边当且仅当树上距离 dis(u,v)C

q 次询问,每次给定 l,r,求只保留图上 [l,r] 内的点和边,图的连通块数量是多少。

解法:

很牛的一个题。

一个想法是,对连通块计数是困难的,但是如果能对于连通块对应成某个东西,对这个东西计数是容易的,题就做完了。

考虑对于每个连通块,找一个点代表整个连通块。这个点对于每个连通块是存在且唯一的。如果这样的点容易刻画性质,那么之后就好做了。

事实上,对于每个连通块,取 BFS 序最小的点作为代表元即可。对于非代表元点,可以说明连通块中必然存在一个点,BFS 序比其小且和其有直接连边。证明考虑每个非代表元,必然存在一条路径和代表元连通,如果这条路径长度为 1 则证毕,否则可以归纳证明。

于是问题转化为求区间中有多少点,满足不存在区间中的其余任何一个点满足 BFS 序小于他,且有直接连边。

考虑处理出 preinxti 表示编号 i 前最大的 BFS 小于 i 的 BFS 序,且距离符合条件的点。nxt 同理。求出后,即询问区间 [l,r] 中有多少 i 满足 prei<lnxti>r。这一部分直接数全局的,然后减去两边的,做三次离线扫描线即可。

如何求出 prenxt 呢?考虑点分治。很好的一点是这里的点分治不需要消除子树内的影响。于是对于每个分治重心将所有点拉出来按照 BFS 序做扫描线,线段树上二分即可。总复杂度 O(nlog2n+mlogn)

Submission Link.

Problem D. P7124 [Ynoi2008] stcm

题意:

你要对于一棵树维护一个点集,支持插入和撤销。你需要在 O(nlogn) 的插入次数内维护出每个点的子树补集。即你需要对于每个点,存在某个时刻,集合是这个点子树补集。

具体来说,n105,你的插入次数不能超过 4.5×106

解法;

做法很多,但有一个十分厉害的分治做法。

考虑 DFS 序,每个点子树对应一个区间,那么子树补相当于前缀加后缀。

考虑直接在 DFS 序上分治,递归到 [l,r] 内,满足已经加入 DFS 序在 [1,l)(r,n] 中的点。对于包含于左右子区间的,插入后,递归处理,然后撤销。对于横跨中间的点,考虑扫描左端点从 lmid,并将右端点移动维护所有要求区间。注意到 DFS 序的极强性质是任何两个子树区间要么不交要么包含,所以指针移动次数必然是对的。

这个做法拓展性很强。对于维护树上子树补的相关问题,大多都可以用这个做法维护。

Submission Link.

Problem E. 区间虚树边集大小

题意:

给定一棵树,不带边权,q 次询问对区间 [l,r] 建虚树,虚树边权和是多少。

解法:

这个其实是比较简单的。

不妨认为每次建立虚树都将根,即 1 号点一起建立虚树。多余的边权其实是 1 到这些点的 LCA 的路径。多出来的部分简单 RMQ 就能处理。

接下来考虑每条边,其在虚树上等价于子树内存在关键点。冷静下来思考一会,这是不是太经典了!对着 r 扫描线,维护每条边最后一次被覆盖位置,相当于询问全局 l 的边数量。树剖上套个颜色均摊段,就做到了 O(nlog2n) 了。

Problem F. 树上邻域数颜色

题意:

给定一棵树,无边权,点有颜色。q 次询问某个点 u 距离 d 的邻域颜色数。

解法:

乍一看很困难啊!

考虑你需要怎么维护颜色数。对于每种颜色,选一个离 u 距离最小的点进行贡献,距离相等随便找一个顺序,比如按照编号。

现在考虑每个点能贡献到哪些点。对每种颜色建立虚树,发现虚树上每条边上,离这个点距离最近的关键点总是一段前缀和一段后缀。首先容易确定对于每个虚树上的点,最近关键点在哪。这部分应该可以 DP 或者直接以关键点为起点跑最短路。然后每条边的前缀后缀切换点是容易求出的。那么每条虚树边上,对于某个关键点的贡献可以被拆成子树减子树,也就是两个 DFS 序区间。所以每个点影响的位置是 O(1) 个 DFS 序区间。现在按照询问点的 DFS 序做离线扫描线,你要做的就变成了单点修改邻域求和。直接点分树维护就可以做到两个 log

Problem G. CF765F Souvenirs

题意:

给定 n 个非负整数 a1,a2,,anq 次询问。每次给定 l,r,在第 l 个数到第 r 个数中选两个下标不同的,最小化两数差的绝对值。你只需要输出最小的差的绝对值。

n105q3×1050ai109

解法:

对于很多这种在一个区间中选两个数并最优化某个东西的题,一个思考方向是是考虑真正有用的元素对 (i,j) 有哪些。

比如对于这个题,确定 i 之后,一个显然的想法是对于所有有用对 (i,j),则对于所有 i<k<j,要么 ak 都大于 max{ai,aj},或者所有 ak 都小于 min{ai,aj}

这玩意不太行啊,因为有用对还是太多了。能不能给力一点?考虑对于 i,不妨设找到了某个 ajai,根据上面这个结论,下个 k 必然有 ak[ai,aj),另外,有 |aiak|<|ajak|,则有 ak<ai+aj2,每次除以 2,最终只有 O(logV) 个有效的右端点。aj<ai 也是同理,这样有用对只有 O(nlogV) 级别。为了快速找出这些有用对,可以按照权值顺序建主席树,在上面二分。这样可以在 O(nlognlogV) 的复杂度内找出所有有用对。然后对着右端点扫描线,用一棵维护区间取 min 的线段树即可。总复杂度 O(nlognlogV+mlogn)

Submission Link.

Problem H. CF1455G Forbidden Value

题意:

已知初始值 x=0,给定 s。有 n 次命令,每次给定下面 2 种命令:

  1. set y v,令 xy,或花费 v 元钱删除该命令;
  2. if y …… end,如果 x=y,执行 if...end 中的命令,否则跳过该 if...end

你需要使用最少的花费,使得无论运行到哪里,都有 xs

1n,y2×1051v109

解法:

考虑整个操作显然是一个树形结构。考虑树上 DP,记 fi,j 表示从 i 子树开始,初始值为 i 上的这个点,最终值为 j 时的最小修改次数。显然这是一个可以整体 DP 的过程,子树合并只需要直接线段树合并,并同时维护区间加区间最小值即可。总复杂度 O(nlogn)

Submission Link.

Problem I. CF1320E Treeland and Viruses

题意:

有一棵有 n 个节点的树,q 次询问(询问互相独立),每次给定 ki 个颜色,每个颜色有一个起始点 vj 和移动速度 sj,每一个颜色在每一次操作中会使它周围没有被染色的连通块上与它的距离不超过 sj 的点全部染为这一个颜色,每一轮中,颜色从 1ki 依次开始操作,一直到所有点全部被染色为止,再询问 mi 个关键点的颜色。

1n,q2×105ki,mi2×105sj106

解法:

考虑每次询问时将颜色点和询问点同时建立虚树,然后跑最短路,在 Dijkstra 之前将所有颜色点扔进队列,同时使用时间和编号的二元组进行排序即可。使用 ST 表求 LCA 可以做到 O(nlogn),如果每次都 O(logn) 求 LCA 可以做到 O(nlog2n)

Submission Link.

Problem J. P10795 『SpOI - R1』Lamborghini (Demo)

题意:

给你一棵无根树,每个点 i 有两个属性 ti,vi

定义有向路径 ijfi,j 为:

  • ijtx 最小的点为 xvjvxvi,则 fi,j=x
  • 否则,fi,j=0

i=1nj=1nfi,j

t 互不相同,1n1051ti,vi109

解法:

此题给予了我们一个另类的刻画树上路径最值的技巧。

如果直接点分治,可能可以通过处理很多东西做出,但是不够厉害。

考虑路径点权最值。对于每条边 (u,v),令其边权为 min{tu,tv},则显然有路径点权最小值等于路径边权最小值。然后考虑对树建立 Kruskal 重构树!这样任意两点 (u,v) 的路径最小值为重构树上 LCA 的点权。枚举 LCA,则只需要维护子树小于等于某数个数。拆成 DFN 序做数点,或者启发式合并,或者线段树合并均可。复杂度 O(nlogn)

Submission Link.

Problem K. CF1575E Eye-Pleasing City Park Tour

题意:

有一个城市公园形如一棵树,它的顶点是 n 个景点,由 n1 条道路连接,第 i 个景点有一个观赏值 ai。每条道路都有一种颜色 ti,如果 ti=0 则为黑色,ti=1 则为白色。同时公园里还配有黑白两种颜色的车。

Caropul 想乘车游览这个公园,但什么颜色的车走什么颜色的道路,想走另一种颜色的道路需要换一次车。

定义一次游览 (u,v) 为走一条从 u 景点开始,到 v 景点结束的简单路径(即路径上的每个景点只能经过一次),f(u,v) 为这条路径经过的所有景点(包括 u,v)的观赏值之和。

现在 Caropul 想知道对于所有不超过 k换车的游览 (u,v)f(u,v) 的和对 109+7 取模的结果,其中 1uvn

注意最开始上车不算一次换车。

解法:

简单点分治。

注意到对于点分治重心,只需要分别考虑唯一的出边是黑或白即可。使用树状数组可以简单做到两个 log

Submission Link.

Problem L. CF2030F Orangutan Approved Subarrays

题意:

有一个正整数集合 S,初始为空。称一个长度为 n 的正整数序列 a1,a2,,an 是好的,当且仅当可以通过若干次如下操作将序列删空:

每次选择序列的一段区间 [l,r] 使得区间中所有数相同,且 alS。删去 al,al+1,,ar,并在 S 中加入 al

给定一个长度为 n 的序列,q 次询问,每次给定区间 [l,r],判断 al,al+1,,ar 是否是好的。

n,q2×1051ain

解法:

考虑固定 l,则使得 [l,r] 是好的的 r 必然是一段以 l 开始的区间。我们希望对于每个 lnxtl 表示最大的合法 r。则询问相当于判断 nxtlr

考虑双指针。容易发现在加入右侧一个数的时候,如果存在某种数,与这个数出现的位置有交但不包含则判定为不合法。考虑目前区间 [l,r],对每个 i[l,r] 维护 prei 表示最大的 j 满足 aj=aij[l,r]。不存在则 prei=+。容易发现往后加和在前面删都是单点修改区间求 min,使用线段树维护,复杂度 O(nlogn+q)

Submission Link.

Problem M. Public NOIP Round7 T4 冒泡排序

题意:

给定一个长度为 n 的非负整数序列 b1,b2,,bn

对于一个长度为 k 的非负整数序列 a1,a2,,ak,一次冒泡排序形如下述代码:

for i = 1 to k-1:
  if a[i] > a[i + 1]:
    swap(a[i], a[i + 1])

给定 q 次询问,每次给定 l,r,k,x,y,将 bl,bl+1,,br 复制到 a1,a2,,arl+1,对 a 进行 k 次冒泡排序后查询 i=xyai

1n1061q5×1050bi109,时限 4 秒。

解法:

好题。

先考虑一个看着可以优化的暴力。

首先我们将 [x,y] 变成后缀差分形式,即 [x,rl+1][y+1,rl+1]

我们枚举值域中的数 x,将区间中大于 x 的数标记为 1,小于等于 x 的数标记为 0。发现询问后缀中所有 1 最终都会在后缀中,同时非后缀中有若干 1 会移动到后缀内。仔细思考发现每次冒泡排序,对于所有 0,只要前面有 1 就会往前一步,所有 1 都会移动到末尾或者下一个 1 前面。那么有多少 1 会从前缀移动到询问后缀呢?事实上,记区间长度 m=rl+1,目前询问后缀为 [i,m]c0[l,r] 表示区间 [l,r] 中标记为 0 的数的个数,c1[l,r] 同理。则我们声称有 min{c1[1,l1],c0[l,l+k1]}1 会从前缀移动到询问后缀。这虽然不容易注意到,但并不难理解。至多有前缀 1 个数能移动到后缀,同时只有 [l,l+k1] 这一段内的 0 能为前面的 1 提供空位。注意到对于序列离散化后枚举值域可以变成枚举 ai,于是得到了一个 O(qn2) 的做法。

但是得到了这个做法之后就没啥难度了。注意到这个 min 随着枚举的 x 增大,一边的值不降,一边的值不升。这个分界点很容易在主席树上二分求出。求完后查询是一个主席树区间询问,直接做就行,复杂度 O(qlogn)

Problem N. P11220 【MX-S4-T4】「yyOI R2」youyou 的三进制数

题意:

现在有 0nn+1 个数。
定义 (x)3 表示十进制数 x 的三进制形式。如果没有特别强调,那么这些数均为十进制形式。

youyou 想构造一个序列长度为 pp1)的非负整数序列 a。使之满足:

  • ai[0,n]
  • 不存在 i,j1i<jp),使得 ai=aj
  • 对于任意 1i<naiai+1 至少满足以下四个条件中的一个:
    1. (ai)3 去掉最后一位,恰好等于 (ai+1)3(若只有一位,则去掉后的数字为 0)。
    2. (ai)3 末尾添上某一位 t(0t2),恰好等于 (ai+1)3(若 ai=0,则添加后舍去前置 0)。
    3. aiw(ai)3 的末尾不是 0,且将末尾的一位数字移到开头与 (ai+1)3 相等。
    4. (ai)3 长度 2,且 (ai)3 次高位非零时,将 (ai)3 开头的一位数字移到末尾,形成的数的十进制值 w,且恰好等于 (ai+1)3

这样的序列 a 被称为“完美的”。

youyou 认为,如果十进制三元组 (x,y,z) 是好的,必须满足以下条件:

  • 0x,y,znxy
  • 存在至少一个”完美的“序列 b,使得十进制下有 b1=xbs=y。其中 s 为序列长度。
  • 存在至少一个”完美的”序列 c,使得十进制下有 c1=z。同时,对于上述任意的 b,均有恰好一对 (i,j),满足 1i|b|1j|c|,使得 bi=cj

对于每一个 0zn,求能构成“好的”三元组 (x,y,z) 的有序对 (x,y) 的个数。

1n3×1050wn

解法:

这么连边真有啥意义吗。

对于所有可以相邻的数连边,事实上可以发现所有边都是双向的。连出后可以发现图一定连通。

完美的序列事实上就是一条简单路径,好的三元组 (x,y,z) 其实就是存在一条从 z 出发的简单路径,使得 xy 的所有简单路径都和这条路径有恰好一个交点。

那么对于固定的 z,哪些 (x,y,z) 是好的呢?我们声称若 xy 的路径有必经点,且存在一条 z 出发的路径经过此必经点,且这条路径不与任意一条 xy 路径在必经点外重合。证明是比较显然的,如果 xy 的所有简单路径与 z 开始的简单路径相交于至少两个点,则必然存在某条简单路径也经过至少两个点。

对图建立圆方树,则判定条件变为 xy 路径上离 z 最近的点为圆点。枚举这个最近点,然后枚举 z 所在子树,做子树加,最后进行查询,直接差分维护 DFN 序即可。复杂度线性。建图若实现不精细则是 O(nlogn) 的。

Submission Link.

Problem O. 云斗学院 2024 S 赛前模拟 T3 魔法序列

题意:

给定一个长为 n 的整数序列 a1,a2,,an,然后给 q 次询问,每次给定 l,r,x,求 maxi=lr(aiORx)。其中 OR 表示二进制下或运算。

特别地,保证 a1<a2<<an

1n,ai,q,x<220,时限 3 秒。

解法 1

对着题解念一遍。

我们考虑先将询问离线。

我们建立两棵 0-1 Trie,第一棵插入值域内所有数,且从低到高位插入。第二棵将所有 ai 插入。然后我们考虑在第一棵上 DFS,在每个叶子节点求所有 x=valleaf 的答案。在 DFS 过程中,我们在第二颗树上动态维护每个数和目前的值的按位或。可以发现在第一棵树上往 1 的边走,其实是在第二棵树上将所有这一位为 0 的子树加 2k。又由于序列单增,所以询问直接类似线段树查询区间 max 即可。由于两棵树建立方向相反,所以复杂度为 O(i=0202i220i+1)=O(VlogV),可以通过。

解法 2

这个做法是 O(Vlog2V) 的,但依赖递增性质是不是有点菜了!

我们考虑从高到低贪心,每次询问变为给定 k,判定区间内是否存在一个数二进制下是 k 的超集,即包含 k

但是这个问题好像有点难啊。但是你别急,考虑什么东西能刻画这种东西。虽然所有数不同,但枚举子集复杂度也太差了,空间显然也不对。但是你考虑你可以 FWT!你希望对于每个值域内的数,维护一棵线段树,线段树上每个位置 i 的权值为 0/1 表示 ai 是否为这个数的超集。FWT 的时候你只需要维护线段树合并。因为你做的是贪心,所以必须在线处理询问,线段树合并时要可持久化一下。这样空间太烂了,只能过 n<21875 分,但确实不依赖于递增的性质。这也是我赛时写的做法。

解法 2 Submission Link.

Problem P. P3747 [六省联考 2017] 相逢是问候

题意:

你要维护一个长度为 n 的非负整数序列 a1,a2,,an,同时给定两个正整数 c,p

一共有 m 个操作,可以分为两种:

  • 0 l r 表示将第 l 个到第 r 个数( al,al+1...ar)中的每一个数 ai 替换为 cai,即 cai 次方,其中 c 是输入的一个常数,也就是执行赋值 ai=cai

  • 1 l r 求第 l 个到第 r 个数的和,也就是输出 i=lrai

因为这个结果可能会很大,所以你只需要输出结果对 p 取模的结果即可。

1n,m5×1041p1080<c<p0ai<p,时限 2 秒。

解法:

考虑一个经典套路。

对于幂塔而言,根据拓展欧拉公式可以递归求解,但事实上可以发现每一步操作模数 p 都会递归变为 φ(p),根据经典结论我们知道,不断执行 pφ(p),最终 p 会在 O(logp) 轮内变为 1。证明考虑若 p 为偶数,则 φ(p)p2,若 p 为奇数,则除 p=1 外,φ(p) 为偶数。

这样我们可以发现,对于每个位置,如果幂塔层数超过 p 变到 1 所需次数,那么对其继续增加层数并不会影响其值,因为递归到最后,其值甚至都不受 ai 的影响。这样我们维护一棵线段树,每个点维护区间内操作次数最小值和区间和。修改暴力递归到所有有意义的叶子节点,然后直接递归求解不超过 O(logp) 层的幂塔。这样总复杂度为 O(nlog3p),其实并不能确保通过。事实上有两种解决方案。一种是注意到数据很弱,将幂塔层数上限调低就可以通过本题,另一种是注意到能优化的复杂度的在快速幂上,我们只需要快速计算 cx 对若干常数取模的结果。模数数量为 O(logp) 量级,对于每个模数光速幂即可。复杂度为 O(nlog2p+plogp)

Submission Link.

Problem Q. CF2009G3 Yunli's Subarray Queries (extreme version)

题意:

给定 n,k 和一个长度为 n 的每个数不超过 n 的正整数序列 a1,a2,,an,对于序列 b1,b2,,bm,其中 mk,定义 f(b) 为最小的操作次数,使得存在一个子区间是公差为 1 的等差数列,操作是每次选任意一个 bi 并将其修改为任意一个整数。

q 次询问,每次给定 l,r,满足 rl+k1,你需要求出 i=lrk+1j=i+k1rf([ai,ai+1,,aj])

1kn2×1051q2×1051ain

解法:

简单题。

容易发现 f(b) 等于序列长度减 ci=biic 的众数出现次数。

离线,对右端点扫描线,你需要维护前缀取 min,区间历史和,直接吉司机线段树上去即可。

代码贺的题解。

Submission Link.

Problem R. P11160 【MX-X6-T6】機械生命体

题意:

维护一个可重集 S,初始为空。支持 q 次如下操作:

  • 1 x,你需要在 S 中加入一个数 x
  • 2 x,你需要在 S 中删除一个数 x。保证此时 S 中存在至少一个 x。如果存在多个 x,则仅删除一个。
  • 3 x k v,你需要对 S 中所有满足 lowbit(xy)2ky 增加 v 并对 232 取模。
  • 4 x,你需要求出 maxySlowbit(xy)。保证此时 S 不为空。

其中 lowbit(x) 表示最大的整数 k,使得 k2 的整数次幂并且整除 x 代表按位异或

特殊的,我们在本题定义 lowbit(0)=232

1q5×105,值域 2321,时限 2 秒,空间限制 512 MB。

解法:

没有操作三是简单的,从低到高位建立 01-Trie,查询直接从低到高匹配就行了。

但是操作三很奇怪,01-Trie 上的加法首先让我们想到的是那个全局加 1 的做法,但是这里加的是 v。显然操作三是一个子树加,但是我们先考虑全局加怎么做。

对于每个点,维护加法标记,下传时,如果标记为奇数,做一次子树加一然后标记减一。将标记除以二后传给两个儿子。进一步地,子树加一可以直接交换左右儿子然后给左子树标记加一。

子树加并不能直接按照全局加将标记放上去,因为事实上这里的加法标记对应的是真正要加的除以 2dep 所得结果,但是子树到根的链上的信息并无法维护。

然而仿照线段树分裂合并,直接将整棵子树分裂出来做全局加,然后合并回去即可。复杂度 O(qlogV)

Submission Link.

Problem S. P11038 【MX-X3-T5】「RiOI-4」Countless J-Light Decomposition

题意:

给定一棵有根带权树,结点以 1n 编号。根结点编号为 1,边权均为正整数。

定义这棵树的剖分为对于每个结点,选择一些儿子(可以都选或都不选)为重儿子的方案。重儿子和其父亲的边称为重边。不是重边的边称为轻边

定义一个剖分是 i 重的,当且仅当对于每个结点,其重儿子数量不超过 i

定义一个剖分是 j 轻的,当且仅当对于每条从根(编号为 1 的结点)出发的简单路径,其经过的轻边的边权和不超过 j

对于 i=0,1,,n1,请求出最小的 j,使得存在一个 i 重的剖分是 j 轻的。

n2×1051w1091 秒。

解法:

先考虑暴力,对于每个 i 进行 DP,记 fu 表示在 u 子树内的答案,转移直接从儿子里取 i 大的转移即可。复杂度 O(n2logn)O(n2)

进一步地,如果某个点儿子数量不超过 i,其 f 值就是儿子的 f 最大值。考虑对于每个 i,建立儿子个数大于 i 的点的虚树,虚树总点数是 O(degi)=O(n) 量级的。转移时直接枚举儿子复杂度不对,但是使用平衡树维护每个点的所有儿子贡献即可。

Submission Link.

Problem T. 傳自我的手機

题意:

Y 先生有 n 个手机,初始他们之间没有联系。他还有整数 u,va1,a2,,an。现在有 q 次操作,操作有四种:

  1. 1 x y:连接 x,y 手机,保证原先手机之间没有连接。
  2. 2 x y:断开 x,y 手机,保证原先手机之间存在连接。
  3. 3 x y:将 ax 修改为 y
  4. 4 x:设 Y 先生手机分为 C1,C2,,Ckk 个连通块,求出 (i=1kjCi(aj+x))moduv

1n,q1051u101v40ai,x,y<104。时限 1.5 秒。

解法:

考虑我们做的本质是,每个点有一个多项式 (x+ai),连通块合并是多项式乘法,答案是所有连通块多项式求和在 x 点的取值。首先离线线段树分治,直接维护多项式问题在于多项式次数太大。仔细观察发现模数很奇怪,有一档部分分是 ux,此时可以发现我们只需要维护 xk(k<v) 的系数。对于 ux,考虑 x=ku+y,其中 0y<x,然后考虑 (x+ai)=(ku+(y+ai)),对于每个不同的 y 维护多项式即可。

Code.

Problem U. CF2048F Kevin and Math Class

题意:

给定 n 和两个长度为 n 的正整数序列 a1,a2,,anb1,b2,,bn。你要进行若干次操作,每次操作选择正整数 1lrn,令 k=mini=lrbi,然后依次对于所有 lir,将 ai 更改为 aik。求使得序列 a 中每个数都变为 1 的最小操作次数。你只需要求出最小操作次数,不需要给出构造。

1n2×1051ai10182bi1018。时限 2 秒,空间限制 1 GB。

解法:

首先,答案不超过 60。每次选择区间 [1,n] 即可。根据计算 1018 不断除以 2 并上取整,60 次就会变为 1

另一方面,显然每次选择的区间必为 b 的小根笛卡尔树上某个点代表的子树区间。

考虑在 b 的小根笛卡尔树上树形 DP,记 fi,j 表示 i 子树内操作 j 次,子树内最大值最小是多少。转移时直接模拟可以做到 O(nlog2V),适当卡常可以通过。

Submission Link.

进一步,对于固定的 i,随着 j 增大,fi,j 单调不增。注意到转移的本质是计算 ci=min0xi(max(ax,bix)),即 minmax 卷积,由于 a,b 单调不升,类似归并排序即可做到 O(logV) 转移。

Problem V. CF2048H Kevin and Strange Operation

题意:

给定一个长度为 n01 字符串 s,你可以进行任意(可以为 0)次操作。特别地,若字符串已经为空,你不能进行操作。

每次操作为:

假设目前串长度为 m,选择整数 1pm,然后对于 1i<p,同时执行 simax(si,si+1),然后删除 sp

问能得到的本质不同非空字符串数量,答案对 998244353 取模。

1n1062 秒。

解法:

操作很奇怪,考虑对于给定字符串 t,能否判定其能被操作得到。

首先有显然的性质,t 中每个字符对应 s 的一个区间的 max。这些区间可能有交。

考虑所有区间,初始有 li=ri=i,即每个区间都为 [i,i](1in),考虑执行一次操作,我们手动模拟一下可以发现,操作的字符对应区间的后面区间不变,操作区间前面的区间左端点不变,右端点变成后一个区间的右端点。进一步地,可以发现假设操作了 x 次,则右端点必然恰好覆盖了 (x,n],左端点可以任意选择 nx 个位置。

于是判定性问题可以贪心,假设进行了 k 次操作,从后往前枚举字符,维护目前的左端点指针,每次往前找第一个需要的字符即可。

然后过程比较简单,发现贪心的过程只维护了操作次数和最大的左端点。考虑 DP,记 fi,j 表示操作 i 次,贪心得到左端点为 j 的方案数。直接转移是 O(n2) 的,无法通过。但是仔细观察转移发现是整体平移和单点修改,维护线段树即可。复杂度 O(nlogn)

Submission Link.

Problem W. CF2041J Bottle Arrangement

题意:

给出长度为 n 的两个序列 a,b,保证 b 中的数两两不同。要求给 b 序列中的若干个数减一并重排,一个数不能多次减一。设重排后的序列为 b,要求 b 满足:

  • b 是非严格单峰序列。
  • 对于所有 1in,有 bi<ai

求减一次数的最小值,或报告无解。

1n5×1051ai,bi109

时限 5 秒。

解法:

看不懂其他题解。

先考虑能否判断答案是否为 0

显然序列 b 的顺序无关紧要,假设 b 小到大排序。

不难发现单峰序列生成方式是,初始序列为空,将 bn 加入序列,然后枚举 in11,将 bi 插入目前序列左侧或右侧。

枚举峰顶所在位置 p。我们可以对于每个 i 求出 ti 表示最大的 bti<ai,也就是说 bi 被确定的时间不超过 ti。然后题意变成你有一个时间戳初始为 n,有一个区间初始为 [p,p],每次时间戳减 1,然后你可以将区间左端点左移 1 或右端点右移 1,并且要求每个位置 i 第一次加入区间时时间戳不超过 ti。显然等价于找到一个区间 [l,r] 使得 lprtl1<n(rl+1)tr+1<n(rl+1),这里假设 t0=tn+1=。这个区间中的位置作为峰顶都是不行的,下文称这些区间为封锁区间。显然一个被其他区间包含的区间没有意义,所以只需要对于每个 l 求出最右的 r 即可。又可以发现 l 固定时限制了一个 r 的范围,并要求 tr+1+r 符合某个大小限制,线段树上二分找到这个位置即可。

已经确定了答案是否为 0,接着考虑如何计算答案。发现一个封锁区间若通过题目中的操作能变为非封锁区间,必然有 tl1=n(rl+1)tr+1=n(rl+1)。对应的花费为 f(al1)f(ar+1)f(x) 定义为若 b 序列中有 x,则 f(x)=1,否则 f(x)=+,对应着能否通过减一操作使得 t 增加一。

不妨考虑 tl1=n(rl+1),此时 r 唯一确定。同理对于 tr+1=n(rl+1)l 唯一确定。于是得到若干区间 [l,r],要选择若干 a 中的数使得每个封锁区间都变为非封锁区间。看似比较奇怪,但是显然如果一个区间只有一侧能操作则只能操作那个数,如果一个区间两侧都能操作,那么必然有 tl1=tr+1,换句话说只需要操作 f(al1)f(ar+1) 较小的那个即可。扫描线枚举峰顶,动态维护所有区间的端点的 a 值的集合即可。

另一方面,有些封锁区间 [l,r] 是不能被操作成非封锁区间的,还是用线段树二分就能找到所有极大区间 [l,r],维护差分即可。

复杂度 O(nlogn)

Submission Link.

posted @   HappyBobb  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示