题目泛刷记录

很多写了的东西暂时不在我电脑里,所以有的先咕咕咕了

P4287 [SHOI2011]双倍回文

题目描述

一个字符串 (s) 的翻转为 (s^R),如果一个子串能写成 (ss^Rss^R) 的形式,那么它就是一个双倍回文子串

求最长的双倍回文子串的长度

题目分析

[SHOI2011]双倍经验

首先对于 (ss^R),它一定是一个偶回文串

于是我们要求的即是两个相同的偶回文串复合的子串的最长长度

这很简单,只要我们判定小于等于当前结点长度的一半的最长回文后缀的长度,是否为当前结点长度的一半即可

于是我们引入广为人知的 (trans) 指针,它维护的即是小于等于当前结点长度的一半的最长回文后缀

对于一个长度小于等于 (2) 的回文串,其 (trans) 指针与 (fail) 指针指向的是同一结点

否则我们不断跳 (fail),直到找到一个满足条件的最长回文后缀

求出了 (trans) 指针,这题也就做完了

P4555 [国家集训队]最长双回文串

题目描述

找出一个最长子串,满足其能分割为两个回文串,输出其长度

题目分析

一眼枚举分割点,然后找出以这个点开始,向前与向后的最长回文串的长度,相加即可

向前很好处理,向后的话只需要反过来再建PAM即可

所有可能的长度取 (max),本题就做完了

P4762 [CERC2014]Virus synthesis

题目描述

原题题面已经很简洁了,这里就不再放一遍了

题目分析

不难想到一个字符串的形成肯定是先利用 (2) 操作生成一个最长的回文串,然后暴力 (1) 操作

于是我们的任务就变成了求生成最长的回文串所需要的操作数

很自然的,我们利用一个数组来存储生成这个点所代表的回文串的最少操作数

对于一个新建的点 (i),我们可以

  • 暴力生成,操作数 (i.len)
  • 在其 (fail) 指针指向的点所代表的的串生成前,加一个字符然后使用一次操作 (2),操作数 (dp_{las}+1)
  • 在其 (trans) 指针指向的点所代表的的串生成前,暴力加字符,然后使用一次操作 (2),操作数 (dp_{i.trs}+(i.len/2-i.trs.len)+1)

对上述操作取 (min) 即可,不断加点,本题就做完了

本题时空有点小卡,需要压缩压缩

P2495 [SDOI2011]消耗战

题目描述

给定一棵树,边有边权

每次给出一个点集,求使结点 (1) 与给定的点集不连通的最小代价

题目分析

首先如果询问的数量不大,我们可以直接树形dp

(f_i) 表示使 (i) 结点与子树中给定的点不连通的最小代价,(S) 表示其子结点集合,(t_i) 表示 (i) 结点是否为给定点集中的点,定义为关键点,(w_{i,j}) 表示连接 (i,j) 两点的边的边权

那么显然有

[f_i=sumlimits_{sin S} egin{cases} w_{i,s}&(t_i=1) \ min(f_s,w_{i,s})&(t_i=0) end{cases} ]

暴力就做完了,现在考虑 (100\%) 的数据

我们发现,这题所有操作给定的点集大小之和并不是很大

也就是说,很多状态都是冗余的

我们考虑给定一个点集之后,哪些点是有用的,哪些点是没有用的

显然,根节点 (1),给定点集中的点都是有用的

还有吗?

观察上面的转移方程可知,两两点的最近公共祖先也是有用的,这也就说明了虚树中不一定只有关键点

然后我们就可以直接去掉没有用的点

对于有用的点的点集,我们不改变他们的祖先关系,重新建树

这题两个点之间的权值就是原树中两点之间的路径上的所有边的边权的最小值

树上倍增,对虚树进行dp即可

CF613D Kingdom and its Cities

题目描述

给定一棵树,同时每次询问给定一个点集,给定点集中的点不能删,求出使给定点集两两不连通的最小删点数量

如果无论如何都会存在两个点连通,输出 (-1)

题目分析

对于这题,无解还是很好判断的

不难发现一个询问无解当且仅当存在至少两个点是父子关系

然后我们仿照上题的套路,建出虚树,然后树形dp

对于两个点如果都是给定点集中的点,那么必须删点

否则就是lca的情况,如果对于这个点的子结点是给定点集中的点的个数超过 (1),那么肯定要删掉这个点,正确性显然

否则上传这个点的子结点中是给定点集中的点的个数

dp完了,这题也就做完了

P4103 [HEOI2014]大工程

我怎么老是忘记删掉#include"debug.h"

代码也是大工程啊

题目分析

首先我们考虑代价和,对于点的路径的长度和,并不是很好统计

但是我们可以直接统计每条边被经过了几次

这是一个简单的工作,或是叫简单的组合数学问题,直接做乘法即可

然后我们考虑最小路径长度与最大路径长度

对于每个点,我们维护四个变量:子树中到本点的最短/最长链,子树中满足条件的最大最小值,向上更新即可

CF449D Jzzhu and Numbers

题目分析

说实话,and背包能想出来,(n) 次FWT也能想出来,但是接下来怎么做确实不会,应该还是理解不透彻&不熟练...

首先这显然是个背包模型:

[f_{i,j}=sumlimits_{a_i&k=j}f_{i-1,k}+f_{i-1,j} ]

观察式子,我们发现左边跟FWT正变换有亿点点相似,暴力做 (n) 次FWT即可

众所周知,对于and卷积,其实就是求一个指标 (i) 的指标超集对应的数的和

于是我们循环对每一项置 (1) 后FWT的结果数列中肯定没有大于二的数

我们可以根据这个性质来优化此题:

  • 如果这一项是 (0),也就是说不做贡献
  • 如果这一项是 (1),也就是说这一项翻倍

不断翻倍,也就是说贡献为 (2) 的幂次方倍,我们只要知道翻倍翻了几次

这简单,找超集个数即整体FWT

然后我们在每一位上累计 (2) 的幂次方倍,然后IFWT即可

P3917 异或序列

SB题

题目分析

拿到题面第一反应就是根据异或的性质,我们可以维护一个前缀和然后循环统计

但是一看数据范围就可以打消这个念头

根据这种二进制题的常见套路,我们可以分别对每个二进制位进行统计

也就是说,对于每一位在 (O(n)) 的时间内统计其所做出的贡献

而这是一个简单的工作,假设现在考虑到第 (i) 位,我们会发现在这一位上的 (1) 将其分成了一个个区间

根据两个相同的数异或值为零的这一性质,讨论一下区间位置的奇偶性即可

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

CF1514D Cut and Stick

题目分析

看到这题不难发现如果一个区间的长度为 (n),并且众数的存在次数为 (x(xgedfrac n2))

那么这个区间内不是众数的数为 (n-x)

(n-x) 个数可以中和 (n-x+1) 个是众数的数

中和在这里的意思是它们在一个区间内

那么剩下的数单独成一个区间,答案即为剩下的为众数的数的数量然后 (+1)

因此,如果设区间的左端点为 (l),右端点为 (r) 的话,答案即为

[min(x-(r-l+1-x+1)+1,1)=min(2x-r+l+1,1) ]

利用主席树求众数,然后更新答案即可

CF1513C Add One

题目分析

一看到题,就可以基本想出对每个数码进行dp,求出其在 (m) 次操作后的长度

求出这个后,我们就可以将输入分解,然后累计答案即可

考虑如何得到 (m) 次操作后的长度

类似倍增的思想,一个数码 (m) 步后的长度其实就是最开始比其大 (1) 的数码 (m-1) 步的长度

注意到 (9) 要进行特殊处理

(f_{i,j}) 表示 (i) 步后数码 (j) 的长度,于是不难得到转移方程:

[egin{cases} f_{i,j}=f_{i-1,j+1}&(j<9) \ f_{i,j}=f_{i-1,1}+f_{i-1,0}&(j=9) end{cases} ]

动态规划即可

P3567 [POI2014]KUR-Couriers

题目分析

求区间众数,利用主席树,对每个位置进行判断

如果其 (l-1) 版本与 (r) 版本的差大于 (frac k 2),那么这就是答案

其中 (k) 表示区间长度

CF1517D Explorer Space

题目分析

首先我们一定可以使用搜索,对每个位置进行扩展

但是这题 (kle20),我们可以利用floyd的思想,对其进行动态规划

最外层枚举现在的步数,不难得到转移方程:

[egin{cases} f_{i,j,k}=min(f_{i,j,k},f_{i-1,j,k-1}+a_{i-1,j})&(i>1) \ f_{i,j,k}=min(f_{i,j,k},f_{i,j-1,k-1}+b_{i,j-1})&(j>1) \ f_{i,j,k}=min(f_{i,j,k},f_{i+1,j,k-1}+a_{i,j})&(i<n) \ f_{i,j,k}=min(f_{i,j,k},f_{i,j+1,k-1}+b_{i,j})&(j<m) end{cases} ]

其中 (a,b) 分别是题目输入的网格图的权值

复杂度 (O(nmk))

CF1515C Phoenix and Towers

题目分析

首先每个元素的值不超过 (x),所以一定有解

于是我们将所有的 (m) 块先置零,放入multiset中

对于每个数,从set中取出最小的块,输出其块位置,表示这个数属于哪个块

然后我们将这个块的值加上这个数的值,然后放回set中

之后不断重复此操作,会发现一定有解,并且得到的一定是可行解

CF1517C Fillomino 2

题目分析

事实上,我们可以对于每个数都尽量的向左扩展

发现行不通之后再向下扩展,此时得到的一定是合法方案

证明的话也很简单,这样扩展得到的一定是一个L形或是Z形,空间并不会有剩余

AT2061 [AGC005C] Tree Restoring

题目分析

本题是让你构造一棵树,满足题目中给定的距离限制

直接做不好做,但是我们可以考虑不会被改变的东西:树的直径

这题只需要判断是否可行,于是我们开个桶存一下每个数就行了

对于一个奇数长度的直径,其上共有偶数个点

形成的长度是 (lceilfrac{len}2 ceilsim len),每个长度分别有两个数对应

如果直径的长度是偶数,其上共有奇数个点,形成的长度是 (frac{len}2sim len)

对于 (frac{len}2) 这个长度,共出现一次,其余点共出现了两次

于是我们将这些长度减掉,如果出现了负数,那么一定不可行

之后我们就是在直径上挂点

长度依然有限制,在这个范围内的长度显然会出现,其余则不会出现

事实上,这个长度的下限是直径长度的一半 (+1)

然后扫一遍即可

CF1516C Baby Ehab Partitions Again

题目分析

CF1120D Power Tree

CF1515D Phoenix and Socks

P5047 [Ynoi2019 模拟赛] Yuno loves sqrt technology II

AT2005 [AGC003E] Sequential operations on Sequence

题目分析

首先要声明的是,你只要被套路过很多次,然后牢记“正难则反”这四个字,本题就已经解决了

事实上,我们发现如果第一步先扩充,第二步再缩小,那么我们可以直接删掉第一步
正确性显然,利用单调栈维护即可

设我们已经用单调栈维护完毕,第 (i) 次操作后的长度为 (l_i)

  • (i) 次的长度比第 (i-1) 次的小
    那么就相当于先算一遍 (1sim l_{i-1}) 中每个次数出现的次数,然后再算一遍 (1sim l_imod l_{i-1}) 中每个次数出现的次数

  • (i) 次的长度比第 (i-1) 次的大
    那么 ((l_{i-1},l_i]) 中肯定有前 (l_{i-1}) 个数的 (k) 次重复,于是我们将前 (l_{i-1}) 个数增加一个系数 (k),表示要被算几次
    然后对后 (l_imod l_{i-1}) 个数(称为取模之后要进行计算的数)进行递归

情况一其实是情况二的特例

假设现在考虑到第 (i) 个数,考虑到不属于取模之后要进行计算的位置的数肯定被增加了系数,递归的时候即解决

于是,现在的问题变成了,如何计算后 (l_imod l_{i-1}) 个数,设共有 (num) 个数

考虑到这些东西肯定也是某个比其 (num) 小的区间的重复,于是我们二分一下找到区间,然后用情况二讨论一下

对于前面的数,增加系数,后面的数递归求解

顺带一提,增加系数是区间加法,但是查询只有最后统计时的一次,利用差分即可

SP5446 FISHNET - Fishing Net

P3852 [TJOI2007]小朋友

题目分析

作为弦图的入门题自然是很简单的

首先我们根据上文有弦图上最大独立集等于最小团覆盖数

我们在求出了PEO后直接贪心即可,正确性也是很显然的

[HNOI2008]神奇的国度

题目分析

这题就是求一个最小色数

于是根据上文,我们只需要求出最大团即可

即求出极大团然后进行 (max) 操作

或是根据MCS的小性质,直接对 (label)(max) 然后加一即可

CF427D Match & Catch

SP694 DISUBSTR - Distinct Substrings

CF802I Fake News (hard)

P3649 [APIO2014]回文串

P5341 [TJOI2019]甲苯先生和大中锋的字符串

P1558 色板游戏

P2894 [USACO08FEB]Hotel G

P2184 贪婪大陆

P4513 小白逛公园

AT4432 [ARC103B] Robot Arms

P5092 [USACO04OPEN]Cube Stacking

P1783 海滩防御

P3830 [SHOI2012]随机树

果然我还是太菜了

题目分析

第一问是叶结点平均深度的期望值,设为 (E(x))

首先我们都能想到展开一个深度为 (i) 的叶结点会得到两个深度为 (i+1) 的叶结点

但是能不能坚持推式子就是做出做不出的关键

(f_i) 表示 (i) 个叶结点的深度值的平均,设第 (i) 个叶结点的深度为 (dep_i)

那么我们依次修改 (dep_i),每次做出 (2+dep_i) 的贡献

[egin{align*} f_i&=dfrac1ileft(sumlimits_{k=1}^idep_k ight) \ f_i&=dfrac1ileft(sumlimits_{k=1}^{i-1}f_{i-1}+dep_k+2 ight) \ &=f_{i-1}+dfrac2i end{align*} ]

再来看第二问:

对于随机变量 (xin N^+)(E(x)=sumlimits_{i=1}^infty P(xge i))

[egin{align*} E(x)&=sumlimits_{i=1}^infty iP(x=i) \ &=sumlimits_{i=1}^infty iP(xge i)-sumlimits_{i=1}^infty iP(xge i+1) \ &=sumlimits_{i=1}^infty iP(xge i)-sumlimits_{i=0}^infty(i-1)P(xge i) \ &=sumlimits_{i=1}^infty P(xge i) end{align*} ]

那么 (E(x)=sumlimits_{i=1}^{n-1}iP(x=i)=sumlimits_{i=1}^{n-1}P(xge i))

此时我们要进行计算的即为树高大于等于 (i) 的概率分别是什么

不难想到对于每棵树我们都可以将其划分为左子树和右子树

(P_i(X)) 为结构 (X) 的高大于等于 (i) 的概率,当前考虑的树结构为 (T),此树结构生成的概率是 (P^prime(T)),显然有:

[P_i(T)=P^prime(T)sum P_{i-1}(L_T)+P_{i-1}(R_T)-P_{i-1}(L_TR_T) ]

我们现在要求一个左子树结点数为 (k),右子树结点数为 (i-k) 的一棵树 ([k,i-k]) 生成的概率

对于 (i=2) 的情况,不难发现 (P([1,1])=1)

现在每次将其等概率展开一个点,显然 (P([2,1])=P([1,2])=dfrac12)

依次类推,我们可以得到任意 (k<i)(P([k,i-k])) 恒等,且都等于 (dfrac1{i-1})

我们设 (dp_{i,j}) 表示 (i) 个叶结点的树的高大于等于 (j) 的概率,上式即为:

[dp_{i,j}=dfrac1{i-1}sumlimits_{k=1}^{i-1}dp_{k,j-1}+dp_{i-k,j-1}-dp_{k,j-1}dp_{i-k,j-1} ]

递推一下,本题就做完了

CF280C Game on Tree

题目分析

此处令一个点选择并做贡献时 (I(X)=1),否则等于 (0)

于是 (E(X)=sumlimits_{i=1}^nE(X_i))

对于一个点,它被选择并做贡献当且仅当它的祖先没有被选择,也就是先于其选择,所以概率为 (dfrac{1}{dep_i})

求和即可

CF398B Painting The Wall

CF148D Bag of mice

原文地址:https://www.cnblogs.com/zythonc/p/14691580.html