2023NOIP前的死亡笔记

Chapter 2

夜神月的《死亡笔记》,写上的题目都会被干掉!

前世(上回)

1. P4284 [SHOI2014] 概率充电器

标签:概率,换根,dp

原来这里有个故事,然后被我删了

这一篇的第一题,写得很详细了。

首先想到进入充电状态的元件个数的期望,即为每个原件进入充电状态的概率和,所以就问题转化为一个点进入充电状态的概率了。

首先乱搞是不行的(或许可以高斯消元?),所以树先定根,目标是求出根节点进入充电状态的概率。由下及上地考虑,这种充电的概率的转移似乎是单向的(向根),如果要解释可以认为是一个点进入充电状态后不会再被考虑,更严谨地想法是考虑树 dp,设一个节点 u u u 在其子树内进入充电状态的概率为 b u b_u bu,它可以被其子树充电或自身直接充电。 b u = p u + ( 1 − p u ) x b_u=p_u+(1-p_u)x bu=pu+(1pu)x,这个 x x x 是被充电(非自发)的概率,即它的儿子能给充电的概率并,转化为先求它的儿子都不能给充电的概率(各儿子不给充电的概率交): ∏ v = s o n ( u ) ( 1 − b v q u v ) \prod_{v=son(u)}(1-b_vq_{uv}) v=son(u)(1bvquv) q q q为初始边概率),然后取补集。那么 b b b 的转移就可以求了: b u = p u + ( 1 − p u ) ( 1 − ∏ v − s o n ( u ) ( 1 − b v q u v ) ) b_u=p_u+(1-p_u)(1-\prod_{v-son(u)}{(1-b_vq_{uv})}) bu=pu+(1pu)(1vson(u)(1bvquv)) r o o t root root 的子树为整棵树, b r o o t b_{root} broot 即为一个点进入充电状态的概率,为答案的 1 n \frac{1}{n} n1 部分。至此写个小暴力可以 O ( n 2 ) \mathcal{O(n^2)} O(n2) 拿到 30pts。code

正解就是换根,从一个已知答案推其他的。记一个点的答案为 f i f_i fi,刚才求的 f r o o t = b r o o t f_{root}=b_{root} froot=broot。我们可以将 ∏ ( 1 − b v q u v ) \prod(1-b_vq_{uv}) (1bvquv) 认为是一个节点与下面节点的直接关系,只要除以一个 1 − b x q u x 1-b_xq_{ux} 1bxqux 就可以删除一个儿子及其子树的贡献,而此部分又可以表示为 b u − p u 1 − p u \frac{b_u-p_u}{1-p_u} 1pubupu,根据这两个性质,还有前面说的单向性,以及你对换根的理解,和你的概率(数学)知识,不难推出下面的转移式(吐血): f v = { 1 − [ 1 − q u v ( ( 1 − 1 − f u − p u 1 − p u 1 − b v q u v ) ( 1 − p u ) + p u ) ] ⋅ ( 1 − b v − p v 1 − p v ) } ⋅ ( 1 − p v ) + p v f_v=\left\{1-[1-q_{uv}((1-\frac{1-\frac{f_u-p_u}{1-p_u}}{1-b_vq_{uv}})(1-p_u)+p_u)]\cdot(1-\frac{b_v-p_v}{1-p_v})\right\}\cdot(1-p_v)+p_v fv={1[1quv((11bvquv11pufupu)(1pu)+pu)](11pvbvpv)}(1pv)+pv 然后,你懂的,化简一下: f v = 1 − ( 1 − q u v ⋅ f u − b v q u v 1 − b v q u v ) ( 1 − b v ) f_v=1-(1-q_{uv}\cdot\frac{f_u-b_vq_{uv}}{1-b_vq_{uv}})(1-b_v) fv=1(1quv1bvquvfubvquv)(1bv) 虽然你是推出来了,但是你的直觉告诉你要特判一下分母为 0 0 0 的情况。但是 m a x ( b v , q u v ) ≤ 1 max(b_v,q_{uv})\leq 1 max(bv,quv)1,所以只要一个不为 1 1 1 就可以了,如果 q u v q_{uv} quv 1 1 1,则根据理解,有: f v = f u f_v=f_u fv=fu 然后实践一下,很简单的。code

我第一次的错误是设 b i , f i b_i,f_i bi,fi 为均不包括自发地充电,这显然是不合理的(早自习没睡醒的原因)。

2. P2851 [USACO06DEC] The Fewest Coins G

标签:背包,抽屉原理

找零和付钱可以分别看作完全背包和多重背包。关键问题在于最多付多少钱可以被找零。设 S i S_i Si 表示 v i v_i vi 的前缀和。则根据抽屉原理,在 S i S_i Si 中有至少一组与 v m a x v_{max} vmax 同余,所以可以在 v m a x 2 v_{max}^2 vmax2 内找到解。

code

3. P9745 「KDOI-06-S」树上异或

标签:树dp,位运算,组合计数

和学校模拟赛的一题很像,可以想到类似树背包的暴力:设 f ( u , x ) f(u,x) f(u,x) 表示在 u u u 的子树中, u u u 所在的连通块的异或和为 x x x不包含 u u u 所在的连通块的权值的方案权值和。初始化 f ( u , x u ) = 1 f(u,x_u)=1 f(u,xu)=1,转移 f ( u , x ) ← f ( u , x ⊕ x v ) × f ( v , x v ) + f ( u , x ) × f ( v , x v ) × x v f(u,x)\gets f(u,x\oplus x_v)\times f(v,x_v)+f(u,x)\times f(v,x_v)\times x_v f(u,x)f(u,xxv)×f(v,xv)+f(u,x)×f(v,xv)×xv。解释:前一项是保留边,后者表示不保留。此方法预期得分 36 ∼ 60 36 \sim 60 3660

正解考虑到 x x x 的转移可以拆位。设 f ( u , i , x ) f(u,i,x) f(u,i,x) 表示在 u u u 的子树中, u u u 所在的连通块的异或和的第 i i i 位为 x x x不包含 u u u 所在的连通块的权值的方案权值和。需要注意的是,这里第 i i i 位并不是指其他位任取,而是把所有其他位的情况看成一种。这样做的意义可以在转移和初始化中体现。

初始化: ∀ i , f ( u , i , x u i ) ← 1 \forall i,f(u,i,x_{ui})\gets 1 i,f(u,i,xui)1。记这个子树中的答案为 a n s ans ans,有 a n s u = ∑ 2 i f ( u , i , 1 ) ans_u=\sum{2^if(u,i,1)} ansu=2if(u,i,1)(0 时权值为 0,统计无意义)。转移: f ( u , i , 0 ) ← f ( u , i , 0 ) × a n s v + f ( u , i , 0 ) × f ( v , i , 0 ) + f ( u , i , 1 ) × f ( v , i , 1 ) f(u,i,0)\gets f(u,i,0)\times ans_v+f(u,i,0)\times f(v,i,0)+f(u,i,1)\times f(v,i,1) f(u,i,0)f(u,i,0)×ansv+f(u,i,0)×f(v,i,0)+f(u,i,1)×f(v,i,1) f ( u , i , 1 ) f(u,i,1) f(u,i,1) 同理。至此,再来解释为什么之前说 “把所有其他位的情况看成一种”,从转移可见,当前状态除了不保留边时涉及儿子的答案(这是在增添权值),其他时候都只与自己那一位有关(纯方案数仅与当前位有关)。

最终答案显然为 a n s 1 ans_1 ans1。复杂度 O ( n log ⁡ x ) \mathcal{O(n\log x)} O(nlogx)

code

4. P7296 [USACO21JAN] Uddered but not Herd G

标签:状压dp

有趣的题,想了很久。

首先考虑重复必然发生在两个被听到的音节间。假如字符有一个顺序 s 1 < s 2 < ⋯ < s n s_1<s_2<\dots<s_n s1<s2<<sn,如果有一个相邻的逆序对出现 s i > s j    , i < j s_i>s_j\;,i<j si>sj,i<j,则在这中间重复唱了,因此歌唱的所有音符中有用的信息是相邻两个音符的二元组。

那么考虑搜索一个最优的歌唱顺序,先知道已经唱过哪些音符,然后再枚举没唱过的音符中下一个唱哪个。如此迭代求最小值即可。因此可以设 f ( s t a t ) f(stat) f(stat) 表示已经唱了的字符( s t a t i = 1 / 0 stat_i=1/0 stati=1/0), f ( s t a t ) = m i n    f ( s t a t    o r    1 ≪ j ) , s t a t j = 0 f(stat)=min\;f(stat\;or\;1\ll j),stat_j=0 f(stat)=minf(stator1j),statj=0。记忆化或是递推都行。

code

5. P1494 [国家集训队] 小 Z 的袜子

算法:莫队

学习新算法。很典型的莫队,因为直接计数不便于求出,所以考虑离线。两个变量 L, R,表示现在计算的区间的左右端点,然后一格格地移动两个端点去匹配下一个询问,以此类推。但是直接搞复杂度肯定过不去,因此考虑一个顺序:将左端点按值域根号分块,则每次左端点最多移动 O ( n ) \mathcal{O}(\sqrt n) O(n ),每个块内保证右端点递增,则一个块内右端点总复杂度 O ( n ) \mathcal{O}(\sqrt n) O(n )。总 n \sqrt n n 个块, q q q 此询问,所以总复杂度 O ( q n + n ) \mathcal{O}(q\sqrt n+n) O(qn +n)

关于这一题,可以维护每个颜色出现次数 c i c_i ci,然后容易得到一个区间的式子 ∑ c i 2 − ∑ c i ( R − L + 1 ) ( R − L ) \frac{\sum{c_i^2}-\sum{c_i}}{(R-L+1)(R-L)} (RL+1)(RL)ci2ci

code

6. iai454 冲突分段

算法:决策单调性dp,莫队,分治

有趣的内容。

暴力做法容易想到:设 f ( i , j ) f(i,j) f(i,j) 表示分 i i i 段,考虑 1 … j 1\dots j 1j 的冲突次数和的最小值。有转移 f ( i , j ) = min ⁡ 1 ≤ k ≤ j ( f ( i − 1 , k − 1 ) + c o s t ( k , j ) f(i,j)=\min_{1\leq k\leq j}(f(i-1,k-1)+cost(k,j) f(i,j)=min1kj(f(i1,k1)+cost(k,j)。复杂度 O ( n 2 k ) \mathcal{O}(n^2k) O(n2k)

然后上式满足四边形不等式,所以决策有单调性,可以分治。 f ( l , r , q l , q r ) f(l,r,ql,qr) f(l,r,ql,qr) 表示当前决策区间 l … r l\dots r lr,最优决策在 q l … q r ql\dots qr qlqr 间,可以先暴力算出中点( m i d = l + r 2 mid=\frac{l+r}{2} mid=2l+r)的答案,然后记其决策位为 p o s pos pos,则可向 f ( l , m i d − 1 , q l , p o s ) , f ( m i d + 1 , r , p o s , q r ) f(l,mid-1,ql,pos),f(mid+1,r,pos,qr) f(l,mid1,ql,pos),f(mid+1,r,pos,qr) 递归。 c o s t cost cost 莫队维护,由于右端点相当于是在二叉树上跳,右端点不变时左端点单调,所以莫队暴力复杂度 O ( n log ⁡ n ) \mathcal{O}(n\log n) O(nlogn),总复杂度 O ( k n log ⁡ n ) \mathcal{O}(kn\log n) O(knlogn)

code

7. CF833B The Bakery

和上一题基本一样,高级的东西要来练练手。

code

8. P4244 [SHOI2008] 仙人掌图 II

算法:圆方树,dcc,dp

如果是圆方树的话,这题作为模板似乎也算正常。

首先复习圆方树:圆方树是处理仙人掌的专用利器。仙人掌图中的边要么是割边要么是环边,但是建圆方树是按点双来建的。步骤多了一部按 dfs 生成树序把原点依次压入栈。为了方便处理单个点组成链的情况,if(dfn[v]) low[u]=min(low[u],low[v]) 此处不需要检测是否 v = p r e v=pre v=pre,这样算方点连到的圆点时便于弹栈。这样做有时单个点组成链的情况在计算上仍需特判(如这题我的解法)。所以当 l o w v = l o w u low_v=low_u lowv=lowu 时,将截至 v v v(包括)的点全弹出,再并上 u u u 就是要连的所有圆点。

然后是这题的特性:不一定要建出圆方树。首先求直径的关键是 ans=max(ans,f[u]+f[v]+1); f[u]=max(f[u],f[v]+1),可以想到,这题对于割边或单个点组成链仍然成立,问题在于环上点。首先处理环会想到断环成链,求 max ⁡ ( f i + f j + i − j ) \max(f_i+f_j+i-j) max(fi+fj+ij),其中 i , j i,j i,j 是两个环上点,且有序( i − j ≤ ⌊ l e n 2 ⌋ i-j\leq\lfloor\frac{len}{2}\rfloor ij2len)。固然想到扫 i i i ,维护 j j j。这里有一种错误的贪心做法,即只维护一个最优决策点,当 i − j > ⌊ l e n 2 ⌋ i-j>\lfloor\frac{len}{2}\rfloor ij>2len 时失去最优决策点,但直接 i++。这样并不是跳到下一个最优决策点,所以伪。具体这里。那么正解是维护单调队列,易证,决策看 f i − i f_i-i fii,其价值降序。

code

9. P5422 [USACO19OPEN] Compound Escape P

算法:状压(轮廓线),dp,搜索,mst

题目大意是给格点图,然后求最小生成树数量。但是这样看是没头绪的。首先发现 K ≤ 6 K\leq 6 K6,这个是很独特的,一般会状压处理(如这题,是状压连通性为点的线段树)。

回到 MST,在一棵树上的一条边必然是割边(废话),所以它可以起到链接连通块的作用。我们此处决策的是边怎么连,所以连通性是要考虑的。不妨用最小表示法表示一行 6 个点的连通性。

可以肯定,这题是状压,这里可以先考虑复杂度,再具体设计算法。如果是纯状压每一行,每次转移情况过多,只好将相邻两行的状态都枚举出来,复杂度至少为 O ( n ( m ! ) 2 ) \mathcal{O}(n(m!)^2) O(n(m!)2),是过不去的,那么就不能这样搞,一定是只枚举一个被压缩的状态。进而想到如果只决策一个点,事情会变得很容易,所以打算做轮廓线状压。预期复杂度 O ( n m ( m ! ) ) \mathcal{O}(nm(m!)) O(nm(m!)),似乎可行。

总结以上两点,我们将以一条轮廓线的连通性的最小表示法为状态。具体地, g ( i , j , x ) ,    f ( i , j , x ) g(i,j,x),\;f(i,j,x) g(i,j,x),f(i,j,x) 分别表示决策 i , j i,j i,j 这个点时,轮廓线状态为 x x x 的最小权值和最小权值时的方案数。转移不难想:如果 j = 1 j=1 j=1,那么只要考虑向上一条边连与否,不然,则考虑向上和向左两条边连与否。这时却发现转移状态要重新构造状态,复杂度为 O ( 4 n m 2 ( m ! ) ) \mathcal{O}(4nm^2(m!)) O(4nm2(m!)),过不了。有一个技巧,就是预处理一个状态可以转移到的状态,避免重复运算,那么复杂度为 O ( m ( n + m ) ( m ! ) ) \mathcal{O}(m(n+m)(m!)) O(m(n+m)(m!)),可过。

code

10. P9021 [USACO23JAN] Subtree Activation P

算法:树上启发式合并,图论

原来,dsu on tree 和 dsu 没有半毛钱关系。。。其实已经写过很多树上启发式合并的题了,但是一直不知道它竟然是这个名字,我是小丑。

关于这题,我在想暴力怎么拿多一点分。目前的想法

经过抽象,可以想到构造一个特殊点 0,然后将它与所有叶子节点以 1 为边权相连,树上边权为两个端点子树大小的差,从 0 到 0,并且经过所有点的回路的最短长度即为答案。

接着,考虑回路性质:每个点度数为偶数,想到设 f ( u , 1 / 0 ) f(u,1/0) f(u,1/0) 表示 u u u 的子树中经过所有点的路径的最短长度,其度数为偶数与否。转移举一个 f ( u , 1 ) f(u,1) f(u,1) 的例子:连 u → v u\to v uv 边时, f ( u , 1 ) ← m i n ( f ( u , 0 ) + f ( v , 1 ) + w , f ( u , 1 ) + f ( v , 0 ) + 2 w , f ( u , 1 ) + f ( v , 0 ) ) f(u,1)\gets min(f(u,0)+f(v,1)+w,f(u,1)+f(v,0)+2w,f(u,1)+f(v,0)) f(u,1)min(f(u,0)+f(v,1)+w,f(u,1)+f(v,0)+2w,f(u,1)+f(v,0)),但是仔细一想发现转移有问题,似乎状态还与该点与 0 的连通性有关,故增加一维状态表示连通性,然后照样推就可以了(慢慢想其实不难)。初始化为与 0 是否直接相通,也很好推。

对我来说这题的关键是每次启发式合并的初始化不能不加考虑。如我一开始直接将上一层的状态来作为初始化,在这题内这是不行的,因为新的一层多加了点,子答案必然增。而如上面第 3 题则可以直接累加方案数。

code

11. P3960 [NOIP2017 提高组] 列队

算法:平衡树,线段树

其实我还不会平衡树,这里提供线段树做法。

n = 1 n=1 n=1 的部分分很有启示价值,不妨先考虑。即维护一个序列,可以查询排在第 k k k 位的元素,且能单点删除,末尾添加新元素。类似于权值线段树的想法,可以让每个存在的元素有 1 1 1 的值,那么按照排列顺序的前缀和即为该点的坐标。这样维护区间和的线段树,单点修改,线段树上分治查询。

再来考虑总情况。按照上面的思路,很容易想到可以把图分为 ( i , 1 ) , ( i , 2 ) , … , ( i , m − 1 )    { i ∈ [ 1 , n ] } (i,1),(i,2),\dots,(i,m-1)\;\left\{i\in[1,n]\right\} (i,1),(i,2),,(i,m1){i[1,n]} ( 1 , m ) , ( 2 , m ) , … , ( n , m ) (1,m),(2,m),\dots,(n,m) (1,m),(2,m),,(n,m) n + 1 n+1 n+1 条线段。这样每个线段都是上文所描述的情况。关于初始化,显然不能 O ( n 2 log ⁡ n ) \mathcal{O}(n^2\log n) O(n2logn) 建树,所以动态开点,一开始区间修改,加上标记,然后容易做到随查随建。总复杂度 O ( q log ⁡ n ) \mathcal{O}(q\log n) O(qlogn)

记得开 long long

code

12. P4246 [SHOI2008] 堵塞的交通

算法:线段树

第一想法是类似于这题,但是因为只有两行,所以没用 dsu,导致这题的分类讨论很繁(但是更不用动脑)。

以列为下标建立线段树,一个节点存储 l … r l\dots r lr 列,但只要记 l l l r r r 两列的相互连通性即可。我写的时候直接看成四个点 bool a[2][2][2][2] 相当复杂,后来发现只要 ( 4 2 ) = 6 {4\choose 2}=6 (24)=6 个变量表示两两连通性即可。转移的讨论最好根据六种连通性来看,不然会像我一样绕晕自己还做错。

总体虽繁而不难,时限很宽松,故不多加赘述。

code

13. P3953 [NOIP2017 提高组] 逛公园

算法:dp,最短路,搜索

绝世好题(因为我不会做啊啊啊)。感觉糊里糊涂地搞出来了。

总之如果一开始想着搞图论坑定没戏(指 dijkstra 最短路计数 30pts),所以要打破极限——dp。其实这里能想到设 f ( u , k ) f(u,k) f(u,k) 表示 1 … u 1\dots u 1u 的路径中长度等于 M i n D i s ( 1 , u ) + k MinDis(1,u)+k MinDis(1,u)+k 的条数。然后似乎会很不自然地想到倒着推(因为正着搞顺序未知,倒着搞可以搜索递归,但是正着应该也是行的),从上一个 f ( v , M i n D i s ( u ) + k − w − M i n D i s ( v ) ) f(v,MinDis(u)+k-w-MinDis(v)) f(v,MinDis(u)+kwMinDis(v)) 转移。然后考虑到无数解的情况是路径中有 0 环,假如 w = 0 w=0 w=0 ,则必然递归会找到两个相同的状态,所以记一下在搜索栈中的元素即可判断。

code

14. P8187 [USACO22FEB] Robot Instructions S

算法:折半,双指针

摆摆烂烂,开始做一些(相对上面的)水题。

显然, N ≤ 40 N\leq 40 N40,加上定向量地游走可以想到折半搜索,这样搜一次 O ( 20 ⋅ 2 20 ) \mathcal{O}(20\cdot2^{20}) O(20220),答案数量为 2 20 2^{20} 220。然后考虑如何合并,自然地会想到 map,但是亲测超时,所以只好老老实实合并答案。不妨将能走到的点按步数分类,然后分别枚举前后的步数,中间双指针扫一下。

code

15. P9126 [USACO23FEB] Moo Route II S

标签:排序,搜索,当前弧优化

贪心地,对于一个并未完全决策的点,应当先去搜索出发时间玩的边,对于不能及时出发的情况先不搜索,对边排序,有单调性,可以二分 O ( log ⁡ n ) \mathcal{O}(\log n) O(logn) 或是当前弧优化,即记下搜索到了那条边 O ( 1 ) \mathcal{O}(1) O(1)。都是可以过的。

特别注意搜索时要包括的是当前决策的时间,并非全局最优时间,不然会重复决策,大大降低效率。

code

16. P9129 [USACO23FEB] Piling Papers G

标签:数位dp,区间dp

学校模拟赛题目,赛时只想到数位,但是愚蠢的我状态设得太繁,本来就会超时的代码还没调出来。这题是非常新颖的思路:dp 套 dp。

典型数位 dp 的套路, [ L , R ] [L,R] [L,R] 的数量等于 [ 1 , R ] [1,R] [1,R] 减去 [ 1 , L − 1 ] [1,L-1] [1,L1] 的数量。然后设状态 f ( i , j ) f(i,j) f(i,j) 表示决策到 a i , x j a_i,x_j ai,xj 的数量,在左边添加不好转移,但又考虑到这是一个左右一点点扩张的模型,进而设 f ( i , l , r ) f(i,l,r) f(i,l,r) 表示决策到 a i , x l … r a_i,x_{l\dots r} ai,xlr 的方案数,接着发现转移时可以通过当前 x l … r x_{l\dots r} xlr 对应上限数字拆位的 l … r l\dots r lr 的大小关系来实现,故认为此法值得考虑。

由于询问密集,不妨对所有 q l , q r ql,qr ql,qr 预处理答案。

具体地,设 S S S 表示上限数字拆位后的字符串,则可设 f ( s t , i , l , r , k ) f(st,i,l,r,k) f(st,i,l,r,k) 表示已决策 a s t … i − 1 a_{st\dots i-1} asti1,当前所有数字长度为 r − l + 1 r-l+1 rl+1 且与 S l … r S_{l\dots r} Slr 的大小关系为小于,等于或大于(对应 k = 0 / 1 / 2 k=0/1/2 k=0/1/2)。其实可以分别对 s t ∈ [ 1 , n ] st\in[1,n] st[1,n] dp 求解,故下文将 s t st st 略去。初始化( g g g 表示求两数大小关系的函数): ∀ i , x      f ( i , x , x , g ( a i , S x ) ) = 2 \forall i,x\;\;f(i,x,x,g(a_i,S_x))=2 i,xf(i,x,x,g(ai,Sx))=2(因为一左一右算两次)。子答案为: ∑ k = 0 / 1 f ( q r , 1 , ∣ S ∣ , k ) + ∑ k = 0 / 1 / 2 , z ∈ [ 2 , ∣ S ∣ ] f ( q r , z , ∣ S ∣ , k ) \sum_{k=0/1}f(qr,1,|S|,k)+\sum_{k=0/1/2,z\in[2,|S|]}{f(qr,z,|S|,k)} k=0/1f(qr,1,S,k)+k=0/1/2,z[2,S]f(qr,z,S,k)(后者位数更少,显然成立,前者只要排除大于的就可)。转移很显然,见代码吧。

code

17. P9017 [USACO23JAN] Lights Off G

标签:思维,dp

思维题,很考验思维,很不错的题。(属于是一做不会,一说就会)

首先暴力可发现答案总不超过 n n n(但是没什么想法去证明)。题目的操作过于复杂,难以直观理解。关于为何要去直观理解是为了将一次操作的影响可以 O ( 1 ) \mathcal{O}(1) O(1) 得到。仔细(艰难)一想,发现一次操作于 d d d 对于 x x x 次另外操作之后的影响为 d … d + x d\dots d+x dd+x 的区间反转(当然要合成环才完全对)。这样就可以 dp 了, f ( i , j ) f(i,j) f(i,j) 表示第 i i i 次操作后状态为 j j j 是否可以转化为 f ( 0 , 0 ) f(0,0) f(0,0)。对于询问可以反过来认为是将模板串一次次异或并平移,即可以枚举操作数然后处理。所以总复杂度为 O ( q n + n 2 2 n ) \mathcal{O}(qn+n^22^n) O(qn+n22n)(听说还可进一步优化)。

切记不要让平移后的状态超数组。

code

18. iai658 彩色树

标签:时序差分,容斥

暴力(30 pts):枚举每一个点为起点,进行 dfs 期间维护每个颜色出现次数,然后对每个搜索到的点加权值。

枚举路径要么不好完全确定,要么要枚举两个点,所以从颜色入手。继续考虑容斥,问题转化为每个颜色总路径数减去不经过该颜色的路径数。对于每个颜色,可以看作树上去掉该颜色的点后的若干连通块,然后每个点数为 n n n 的连通块贡献 n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n1) 条路径。枚举这样的连通块可以进一步转化为枚举该颜色的点,其儿子所在连通块(以及总的根节点)。这可以通过在遍历时维护一个节点个数 sum,以及每个颜色需要减去的量(因为连通块并非完整的子树,可能被子树中相同颜色的点阻断),然后两者变化量之和即为连通块大小。更具体的实现见代码。

code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值