CQ 省集游记 模拟赛部分
day1
-
qoj 13543
比较神秘的卡常题,思路是很容易的,发现可以少两次也是很容易的大概写了半个小时多点。
-
qoj 10215
过于套路的题目。
一方面是 DP套DP,先考虑 \(f_{i,0/1}\) 表示选没选的最小点覆盖,发现 \(f_{i,0}\le f_{i,1}-1\) 时才会有用。
且 \(f_{i,1}-f_{i,0}\le 1\),则说明我们只需要重新记录 \(g_{i,0/1}\) 表示选了不劣于不选,选了比不选多用一个。
考虑到 \(g\) 的转移是类似于 \(f\) 的。
然后考虑带权,注意到连通块边界的都得是 \(1\),其余是 \(2\),那么只需要记录一下最后合并连通块根的答案时有几个儿子,这样好分配系数,只需要记录 \(0,1,\ge 2\) 个即可。
再考虑幂的限制,用斯特林数转下降幂,得到组合意义选了多少个点,后面用斯特林数还原答案即可。
-
qoj 15436
事实上我们只关心 \(|S|,|N(S)|\),如果把所有的这样的点扔在平面上 \((x,y)\),就相当于给点分配权值,使得权值和不超过 \(1\),且 \(\sum v_i(ax_i+by_i)\le K\) 且 \(\sum v_i\le 1\) 且最大化 \(\max \sum v_iax_i\)。
这个问题是很经典的,你应当不会给多个点分配权值,比如考虑上凸的三个点,把中间那个点按照 \(\Delta x\) 等比例分配给左右两个点,得到的必然合法,且 \(\sum v_ix_i\) 不差。
考虑任意 \(3\) 个点,不妨设为 \((x_1, y_1), (x_2, y_2), (x_3, y_3)\) ,且 \(x_1 \le x_2 \le x_3\) 。
令 \(L = x_2 - x_1, R = x_3 - x_2\) ,就会有 \(Rx_1 + Lx_3 = (L + R)x_2\) 。若 \((x_2, y_2)\) 在 \((x_1, y_1), (x_3, y_3)\) 连线的上方,设其原本的权值是 \(w\) ,则我们为 \((x_1, y_1)\) 分配 \(\frac{R}{L + R}\cdot w\) 的权值,为 \((x_3, y_3)\) 分配 \(\frac{L}{L + R}\cdot w\) 的权值,并清空 \((x_2, y_2)\) 的权值。可以验证这合法且不劣。
否则我们可以同理地把两边的权值分配到中间,同样能得到合法且不劣的解,并且此时至少有一个点权值为 \(0\) 。可以容易继续发现我们只需要下凸壳的连续两点即可。
求出凸壳后,相当于找 \(ax+by\le K\) 这个半平面截凸壳前后的两个点,这是容易二分的,由于凸壳不会太大只有 \(O(n^{\frac{2}{3}})\) 暴力也是可以的。
如何求?考虑我们知道凸壳上一定有点 \((0,0),(n,n)\), 考虑凸壳上一个点需要满足叉积 \(>0\),因此相当于左边选一个点给 \(\Delta Y\),右边选一个点给 \(-\Delta X\)。如果要最大化的话就是最大权闭合子图了。
即:
\[-(x_R-x_L)y+(y_R-y_L)x>y_Lx_R-y_Rx_L \]然后就做完了,用分治求一下即可。
day2
神人 xqw 的神人题目。
-
交互库有一个隐藏的 \(1\) 到 \(n\) 的排列 \(p\) 。每次询问你可以给出两个数 \(u,v\) 满足 \(1\leq u,v\leq n\) ,交互库会返回两个数在排列中的距离对 \(3\) 取模的结果。即找到 \(p_i=u,p_j=v\) ,返回 \(|i-j|\bmod 3\) 。
保证排列的生成方式为:确定长度 \(n\) 后,在所有满足子任务限制,且满足 \(p_1<p_n\) 的排列中等概率随机一个。
你需要在 \(4\times 10^5\) 次询问内求出隐藏的排列。具体的评测细节参见【评分方式】。\(n\le 1e4,14000\) 次获得满分。
最开始想的是快速排序,大概就是先划分颜色(可以直接 \(\frac{5}{3}n\),就先取一个点,\(O(n)\) 知道同色,再取一个不同色的问),然后同色是无法区分的,但异色是可以划分左右的。
于是先随便取一个颜色,将其他两个颜色根据返回值分到左右两侧,接着考虑如何划分本颜色。
可以将划分到左侧的所有异色来扫,对于两个颜色不同的异色点,我可以区分其前后顺序。
由此双指针就能以 \(O(L)\) 的复杂度找出最接近的元素。以此划分我自己这个颜色。
一些启发式:找 \(O(\min(L,R))\),中心点取三个颜色集合里最大的那个的中的随机一个,缓存一些询问。
开头的时候 \(O(\frac{5}{3}n)\) 就能将两个颜色划分开左右,只需要再给点代价找最近中间的就能继续递归了。
可以压到 \(17n\) 左右,期望是 \(\frac{4}{3}n\log n\) 左右,\(85\) 分。
快速排序是不稳定的,在;此类压很紧的题目中,是不适合快速排序的。
除了这个,常用的还有归并排序和插入排序,归并排序显然不适合,考虑插入排序。
分为三组 \(A,B,C\) 先考虑合并 \(AB\) 使得其有序。
交替插入 \(A,B\),动态的,目前肯定只能有 \(A,B\) 的相对顺序,即我们可以将序列划分为 \(A\) 一段 \(B\) 一段……,段内不区分。
值比如插入 \(A\),先二分在哪个 \(B\) 段内(每个段取一个代表元素即可)我知道这个 \(A\) 肯定是在当前段的某一截内,可以 \(O(len)\) 地将这一段割开。
可以发现其次数事实上是 \(2\sum_{i=1}^{\frac{n}{3}} \log i+\frac{n}{3}\log\frac{2}{3}n+O(n)\),也就是根据斯特林公式有 \(n\log n+O(n)\)。
实际上是 \(13.5\) 次左右。
-
给定一棵 \(n\) 个点的树 \(T\) ,点的编号为 \(1\) 到 \(n\) 。对于值域为 \([n]\) 的序列 \(\{a_1,a_2,\dots,a_\ell\}\) ,定义该序列是好的,当且仅当可以通过若干次如下操作将其排序:
选择两个下标 \(1\leq i<j\leq \ell\) ,满足编号为 \(a_i\) 和 \(a_j\) 的点在树 \(T\) 上相邻,然后交换 \(a_i\) 和 \(a_j\) 。
给定常数 \(m\) ,对于 \(\ell\) 从 \(1\) 到 \(m\) ,输出好的序列的个数,对 \(10^9+7\) 取模。
本场唯一切了的题。
注意到连通块内的是随便排序的。
也就是一个合法序列,把所有值都在树上标记一下,然后只需要每个连通块内部排序后树有序即可。
那就考虑连通块是:
\[\sum_{\text{划分} C_1\sim C_m}\prod_{i=1}^m\sum_{t}{t\brace |C_i|}|C_i|! \]有了这个已经可以做了。
考虑斯特林数的 OGF。
\[\sum S(n,k)x^n=\frac{x^k}{\prod_{i=1}^k(1-ix)} \]则有原答案一定是一个:
\[F(x)=\frac{P(x)}{Q(x)} \]由于你就算把分母全部通分,一个 \((1-ix)\) 的系数最高就是 \(\lfloor\frac{n}{i}\rfloor\),则可以假装
\[Q=\prod_{i=1}^n(1-ix)^{\lfloor\frac{n}{i}\rfloor} \]那么 \(P\) 就只能是一个 \(O(n\ln n)\) 阶的多项式了。
怎么搞呢,可以直接插值,枚举 \(x\),算出 \(f(C,x)\) 大小为 \(i\) 的连通块取值 \(x\) 得到的值(原多项式除以 \(Q(x)\) 的值)。
用 \(dp_{i,j}\) 当前连通块根为 \(i\) 大小 \(j\),合并一个大小的连通块的时候乘以 \(f(C,x)\) 即可。
这样你完全可以通过插值插出来 \(P(x)\)。
然后转线性递推即可。
-
需要你完成一个任务。俱乐部可以被看做一个包含 \(n\) 层楼的大楼,从下到上第 \(i\) 层楼的高度为 \(h_i\) 。每一层楼上有一个人,初始第 \(n\) 层楼的人手上拿着一个小球。
若第 \(i\) 层楼上的人拿着小球,他可以将小球向下扔,初速度可以在 \(0\) 到 \(v_i\) 之间任意选择一个非负实数。注意:小球的初速度方向一定为竖直向下。
在小球自由落体的过程中,当小球经过第 \(i\) 个人身边时,若小球的瞬时速度不超过 \(l_i\) ,则这个人可以接住小球。接住小球后他可以继续将小球向下扔。
若小球被第 \(1\) 层楼的人接住,则任务完成。否则若小球在被第 \(1\) 层楼的人接住前碰到地面,任务失败。不妨设重力加速度为 \(g=1\) ,且接球和扔球的时间忽略不计,你需要求出完成任务需要的最短时间,或者声称无法完成任务。数据结构练习题啊。
写出 DP 列清楚关系后直接上李超树维护。
一类转移是李超树插区间直接维护。
一类转移是先CDQ,在分治每一层的时候用全局李超树。
坑点: 在此题中,虽然函数有定义域 \([L_i,R_i]\),但查询的所有 \(X\) 都满足 \(X\le \min R\)。
此刻不能够直接上足够大的界的李超树,维护是有问题的,应当直接把上界设置为 $\min R $。
原因是分段函数不能够直接上李超维护(需要保证唯一交点)
day3
这套题更神秘了。
-
有一个字符集为小写字母的字符串 \(S\) ,你需要通过以下方法构造出这个串:
第一步:先构造若干回文串,并将其依次拼接,拼出的串记为 \(S'\) 。
第二步:重复进行若干次:选择 \(S'\) 中两个相邻且相同的字符,一起消除。
最终需要使得 \(S'=S\) 。
你需要给出构造方案,并最小化第一步中使用的回文串个数。
为了保证输出量,还要求每个回文串串长 \(\le 2|S|\) ,可以证明这个限制不会改变回文串最小使用个数。先考虑这个个数是什么。
注意到第一部分中不可能使用偶回文串。原理是如果使用了,那么我可以找到与奇回文串相邻的一个偶串,在奇串另一端也放一个,这样放的那一个最后也可以被消去,不影响答案。
因此只会有奇串。
同时奇串的中心一定不会被消去,如果被消去了,则说明参与消除的这一段与我这个串的另一半相同,则我完全没有必要最开始放这个串。
因此也不会中心被消去,问题成功转化为,需要删去多少个中心,原串可以被消去。
\(f_{i,i}=1,f_{i,i-1}=0\),\(f_{l,r}=\min(f_{l,k}+f_{k+1,r})\),若 \(a_l=a_r\) 也可以从 \(f_{l+1,r-1}\) 转移。
输出方案是shit。
-
无人通过的题目。
以下所说的所有 \(m\) 进制 \(D\) 位的数,允许高位有前导 \(0\) 。
小 \(h\) 有 \(n\) 个 \(m\) 进制 \(D\) 位的数 \(A_1,A_2 \cdots A_n\) 。
在做加法前,大 \(H\) 会对其进行变换:随机选择一个下标与值域都为 \([0,m-1]\) 的序列 \(P\) ( \(m^m\) 种情况),将每个数的每个位的值,从 \(x\) 变成 \(P_x\) 。变换后的数记为 \(B_1,B_2 \cdots B_n\) 。
小 \(h\) 有 \(Q\) 次询问,每次给出 \(X\) ,他想要知道,在随机变换后,有多少个有序对 \((i,j)\) , \(1 \le i,j \le n\) 满足 \(B_i+B_j \le X\) ,对于所有变换情况求和。其中 \(X\) 也是 \(m\) 进制 \(D\) 位的数。注: \((i,j)\) 和 \((j,i)\) 是不同有序对。
答案对 \(10^9+7\) 取模。考虑暴力如何算。
即 \(B_{i}+B_j\le X\) 这种东西,可以数位 DP。
比如设
solve(dep,flg,vector<limit> lim)表示到了 \(dep\) 层,目前有没有要求进位,目前的限制是什么。就会有:当前层如果要到下一层,则必须取
X[t]+flg*m,flg_new=0或者X[t]+flg*m-1,flg_new=1这种。否则就是
<=X[t]+flg*m-2终止。所以会面临局面:\(a_i+b_i=c_i\) 以及有且只有一个的 \(a_t+b_t\le c_t\)。
就变成了解方程,但这个东西非常恶心难写,大概就是根据不等式写每个元素的取值范围(将唯一一个不等式的 \(a_t\) 看作变量 \(x\),然后用其带换所有的变量)。
这里大概是一个 \(D\log D\) 或者实现差一点 \(D^2\log n\) 的东西。
那么如何优化我们的枚举呢?
关注方程的形态,两个局面如果通过编号的映射可以相同,则本质相同。
因此,不妨考虑 \(Bell(2D)\) 去划分一个局面,问题在于统计一个局面的方案数。
可以这样做:先按照 \(Bell(D)\) 给每个数字分类。
然后对每个数字,再去枚举另一个数字的形态(类似于有初始这么多个颜色,再暴搜填颜色)
问题就变成了固定一些位置的值,且再钦定一些位置值相同,求这样的值个数。
可以对每个数字的出现位置做哈希来统计,被钦定值相同的位置同样可以哈希,也就是一个 \(2^D\times n\) 最多的东西。
这个类似于钦定相同,所以需要一点点容斥,其实也很简单,就是倒着推即可,推的时候枚举那两种颜色被算成一样的了,减掉就是。
这个可以对 \(Bell(D)\) 分类后再做,就是 \(Bell(2D)\times Bell(D) \times D^2\) 且远远跑不满的东西了。
复杂度 \(O(Bell(D)\times poly(D))\)
-
有 \(n\) 个集合 \(S_0,S_1 \cdots S_{n-1}\) 。最初,集合全都为空。
在线执行 \(m\) 次操作,每次操作是以下两种之一:\(1\) , \(x\) , \(l\) , \(r\) : \(\forall i \in [l,r]\) ,若 \(x \notin S_i\) ,将 \(x\) 加入集合 \(S_i\) 。
\(2\) , \(l\) , \(r\) :查询 \(\max_{i \in [l,r]} \texttt{mex}(S_i)\) 。集合的 \(\texttt{mex}\) 定义为最小的不在集合内的自然数。第一行输入三个数 \(n,m,op\) 。其中 \(op \in \{0,1\}\) 为是否进行了加密。
接下来 \(m\) 行,按照格式输入操作。
若 \(op=1\) ,则需要对首次询问之后输入的所有 \(l,r,x\) 都异或上一次询问的答案,才是真实值。这算是经典问题了。
考虑对每个值,维护“禁止区间”集合,最初所有值的禁止区间都是 \([1,n]\)。
集合 \(S_i\) 的 \(Mex\) 就是最小的值,满足其禁止区间包含点 \(i\)。
将这个限制挂在线段树上,设 \(val_x\) 为线段树节点 \(x\) 的最小禁止值(即禁止区间集合包含 \(I_x\) 的值最小值)。
如何求一个区间的最大 \(Mex\) 值呢?可以维护 \(res_x=\min(val_x,\max(res_{lc},res_{rc}))\)。
则 \(I_x\) 里的 \(Mex\) 最大值,就是 \(\min(h_x,res_x)\),其中 \(h_x\) 是从根到 \(x\) 路径上所有点的 \(val\) 最小值。
如何带修?用
set维护每个值的禁止区间,每次给一个区间加入这个值,相当于禁止区间扣掉这些东西。在线段树上每个点也开一个
set维护所有的禁止信息,支持删除插入并重置 \(val_x\) 即可。复杂度 \(O((n+q)\log^2 n)\),修改次数均摊 \(O(n)\)。
day 5
day 4 是分享,没有。
-
T1 是很简单的题,这里就省略了。
-
T2 是密码卡常+无聊题。
-
T3 是乱搞题。
对于非负整数 \(z\) 和一个非负整数集合 \(S\) ,设 \(f_z(S)=\{x\oplus z\mid x\in S\}\) ,即 \(f_z(S)\) 为 \(S\) 中所有元素异或上 \(z\) 得到的集合。若 \(S=f_z(S)\) ,则称 \(z\) 是 \(S\) 的不动点。
给定非负整数集合 \(S\) ,求 \(S\) 的所有不动点。首先,给所有 \(S\) 的元素和所有有解的 \(z\) 同时异或一个元素毫无问题。
因此可以假定 \(0\in S\),那么就能说明解一定是 \(S\) 内元素。
官方做法:
给每个值随机赋权 \(w\)。
对于数字 \(x\),求 \(\sum_{y\in S} w_{x\oplus y}\),可以 FWT 算。
若 \(val_x=\sum_{y\in S} w_y\) 就认为这是一个正确的解。
如何缩小值域?找一个值域 \(k\),生成 \(k\) 个数 \(v_0\sim v_{k-1}\)。
对于每个 \(x\),将其映射到数字 \(y\),满足 \(y_t=|(x\& v_t)|\bmod 2\),即点积。
再做即可。
做两次就有足够高的正确率。
考虑这个映射方法为什么优秀?
一方面,\(f(x\oplus y)=f(x)\oplus f(y)\),可以判对。
并且,如果会判错,则每一位有独立的错误概率是 \(\frac{1}{2}\)。
其实这是不必要的。
一方面,我们注意到解组成一个线性基(若 \(x\) 合法,\(y\) 合法自然 \(x\oplus y\) 合法),因此可以打乱之后暴力
check,如果当前点已经可以被线性基表出了,则可以跳过检验。这还是不太优,如果答案很少的话。
那么,如何快速筛掉非法的答案呢?
若值 \(v\) 满足与 \(v\) 点积为 \(0/1\) 的数字个数不同,则与 \(v\) 点积为 \(1\) 的元素 \(z\) 都是会被毙掉的。
设 \(S_0(v)=\lbrace x\in S|x*v=0\rbrace,S_1\) 同理。
由于 \((x\oplus y) * v=(x*v)\oplus (y*v)\)。
则 \((x\oplus z)=(x*v)\oplus (z*v)\)。
随机 100 个数,检验一下,然后把成功非法的存一个
vector里,每次要检验一个值的时候先用这些检验一下即可。
day 6
每个 day 6 都会 AK 一车子人
前两题都是沙比题,不说了。
平面上有 \(n\) 个角,其顶点坐标分别为 \((1,0),(2,0),\cdots,(n,0)\) 。第 \(i\) 个角的大小为 \(a_i\) 度,其中 \(a_i\) 是 \([1,179]\) 范围内的整数。
每个角会均匀随机地选取它所朝的方向。形式化地,每个角会随机一个实数 \(\alpha_i\in [0,360)\) ,第 \(i\) 角的两条边与 \(x\) 轴的夹角分别为 \(\alpha_i\) 度和 \(\alpha_i+a_i\) 度。
求所有角互不相交的概率,对 \(998244353\) 取模。两个角相交是指,存在平面上的一个点,它同时处于两个角内部。\(1\le \alpha _i\le 179\)
考察一个概率,跨过 \(x\) 轴线的角最多只有两个。
讨论一下:
-
如果有 \(k\) 个角在 \(x\) 轴上方,度数为 \(b_1,b_2,\cdots,b_k\) ,则合法概率为
\(\frac{(180-b_1-b_2-\cdots-b_k)^k}{k!}\) -
\(x\) 轴下方的合法概率类似,合法概率为
\(\frac{(180-c_1-c_2-\cdots-c_{n-k})^{n-k}}{(n-k)!}\) -
假设最左侧的点跨过 \(x\) 轴。设它有 \(x\) 度在上半平面,则概率为
\(\frac{(180-x-b_1-b_2-\cdots-b_k)^k}{k!}\cdot\frac{(180-(a_1-x)-c_1-c_2-\cdots-c_{n-k-1})^{n-k-1}}{(n-k-1)!}\)总概率即为这个式子关于 \(x\) 的积分
可以用背包算出来固定 \(k\) 和 \(\sum b\) 的方案数,得到对一个指数函数的积分,暴力打开多项式,套用积分公式即可。
注意这里要求 \(\max(0,180-a_1-\sum c)<x<\min(a_1,180-\sum b)\)。
即有上下界的积分。
最右侧同理。
-
如果两侧都跨过 \(x\) 轴,设左侧有 \(x\) 度在上半平面,右侧有 \(y\) 度在上半平面,则概率为
\(\frac{(180-x-y-b_1-b_2-\cdots-b_k)^k}{k!}\cdot\frac{(180-(a_1-x)-(a_n-y)-c_1-c_2-\cdots-c_{n-k-2})^{n-k-2}}{(n-k-2)!}\)同样是背包算出 \(\sum b,k\) 固定的方案数。
可以发现,这一方面要求 \(0<x<a_1,0<y<a_n,\max(0,180-\sum c-a_1-a_n)<x+y<\min(a_1+a_2,180-\sum b)\)
即 \(x,y,x+y\) 都带上下界的积分。
这个多项式如何处理出来?枚举 \(\sum b\),考察 \(k\) 逐步移动,可以每次 \(O(n)\) 处理出这个新多项式。
这样就只需要 \(360\times n^2\) 处理了。
接着考虑这个积分怎么算,不妨设 \(L,R,x\le A,y\le B\),相当于是:
\[f(A,B,R)=\int\int_{\substack{ 0\le x\le A \\ 0\le y\le B\\ 0\le x+y\le R}}F(x+y)dxdy \]算 \(f(A,B,R)-f(A,B,L)\)。
来考虑容斥 \(A,B\)。
\[\begin{aligned} f(A,B,R)&=\\ &+\int_{\substack{x\ge 0,y\ge 0,x+y\le R}}f(x+y)\\ &-\int_{x\ge 0,y\ge 0,x+y\le R-A}f(x+y+A)\\ &-\int_{x\ge 0,y\ge 0,x+y\le R-B}f(x+y+B)\\ &+\int_{x\ge 0,y\ge 0,x+y\ge R-A-B}f(x+y+A+B)、、 \end{aligned} \]可以有:
\[\begin{aligned} g(u,lim)&=\int_{x\ge 0,y\ge 0,x+y\le lim}f(x+y+u)\\ &=\int_{x\le lim}x\times f(x+u)\\ &=\int_{u\le x\le lim+u}(x-u)f(x)\\ &=\int_{u\le x\le lim+u}xf(x)-uf(x)\\ \end{aligned} \]这下计算就非常容易了,只需要求一阶积分即可。
day 7
-
T1 是简单网络流题。
-
定义一个值域为 \([1,n]\) ,长度分别为 \(k,n\) 的数组对 \((a,p)\) 是好的,当且仅当:
\(\forall 1\leq i\leq k, a_{k-i+1} = p_{a_i}\) 。
给你一个值域为 \([1,n]\) ,长度为 \(n\) 的数组 \(a\) ,对于 \(a\) 的 \(\frac{n(n+1)}2\) 个子段 \(a'\) ,以及 \(n^n\) 个值域为 \([1,n]\) ,长度为 \(n\) 的数组 \(p\) ,求出好的数组对 \((a',p)\) 数量,对 \(998244353\) 取模。
这个人赛时打了 \(\log^2\) 整体二分获得 \(80\)。
先来考虑暴力的做法,只需要考虑限制:对于对称的两个数字 \(x,y\)。
- \(x=y:p_x=y\)
- \(x\neq y,p_x=y,p_y=x\)。
所以答案就是 \(n^{n-c}\) 其中 \(c\) 是出现数字次数。
整体二分的说法就是,我们尝试对每个回文中心,找到最大的扩展长度,使其合法。
当我们找到 \(W_i:\) 最大扩展长度后,就可以直接扫描线了。
考虑如何求出 \(W_i\)。
题目条件本质上在说什么?相当于“相等关系结构相同”,即提取出这一段后,将每个元素替换为距离其上次出现的距离 \(i-pre_i\),然后再从后往前也替换为距离其上次出现的距离(\(suf_i-i\))。
将从后往前的串反过来,就和从前往后的是一样的。
只不过有区间 \([l,r]\) 限制而已。
整体二分,然后扫描线,扫到一个元素时,其上个出现的位置的“后距离”被更新,同时,对于 \(L\le pre\) 的区间,加入的这个值的“前距离”也被更新。
则就是单点修改,可以拿出正向哈希和反向哈希,凑一下幂次就能判断了。
最后扫描线,我们只需要关注每个点,\(i+nxt_i\) 与回文中心的关系即可知道其对 \(n^{n-c}\) 中的 \(c\) 的贡献是 \(0/1/2\) 的哪一个了。
- \(i+nxt_i<2mid:0\)
- \(i+nxt_i=2mid:1\)
- \(i+nxt_i>2mid:2\)
这样就能扫描线处理了。
显然这比较差,如何做的更好?
manacher:注意到这个序列满足其回文性质
回文/类回文串统计问题:思考manacher
设 \(p_i\) 为半径,\(f_i\) 为合法子段答案,\(g_i\) 为这个最外层区间的自由变量数。
我可以算出增大或者缩小半径时 \(g\) 的变动,从而维护 \(f\) 的变动。
类似于马拉车算法,我们可以直接复制原那一段的 \(f,g\) 值,超出边界的部分重置。
需要在能够更新 \(r\) 就更新,即 \(i+p_i-1\ge r\) 直接更新而不是 \(>\)。
这样复杂度就是 \(O(n)\) 了。
需要要求的性质:
有两个区间 \([L,R]\) 与 \([l,r]\) ,满足 \(L\leq l\leq r\leq R\) ,找到 \([l,r]\) 关于 \([L,R]\) 的对称区间 \([l'=R+L-r,r'=R+L-l]\) ,有结论:当 \([L,R]\) 是好区间时:
\([l',r']\) 是好区间当且仅当 \([l,r]\) 是好区间。
当 \([l,r]\) 、 \([l',r']\) 均为好区间时,其对应排列的已确定 \(p,p'\) ,在经过区间 \([L,R]\) 的排列 \(P\) 的映射后,完全相同。 -
T3 好难绷的题目。
由于 T2 被带偏了所以秒了。
定义一个长度为 \(k\) 值域为 \([1,m]\cap \mathbb Z_+\) 的字符串 \(s\) 的生成字符串为,枚举所有大小为 \(m\) 的排列 \(p\) ,字典序最小的 \(p_{s_1}p_{s_2}\dots p_{s_k}\) 。
有一个长度为 \(n\) 值域为 \([1,m]\cap \mathbb Z_+\) 的字符串 \(S\) ,你需要求出其所有子串的生成字符串的种类数。注意到将每个元素替换为距离上个出现位置的距离。
就可以描述相同类型的生成字符串了。
所以暴力的办法就是直接主席树先倒着暴力预处理所有位置。
然后用哈希做比较,暴力 \(O(n\log^3 n)\) 后缀排序。
接着 \(O(n\log^2 n)\) 求 LCP。
就做完了。
如何优化?
可以将主席树换成分块压复杂度,变成 \(n\sqrt n+n\log^2 n\),因为它可以 \(O(1)\) 查询。

浙公网安备 33010602011771号