UOJ#433. 【集训队作业2018】串串(循环串/回文串)

博客介绍了如何解决UOJ#433题目,涉及弱双回文串的性质,如最长回文前缀和后缀,整周期串的概念,以及如何利用回文树、线段树和lca来统计本质不同的双回文串划分。此外,还提到了算重问题和本原平方串的处理,通过O(nlogn)的时间复杂度实现算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

题解:
这道题主要用到的几个性质(具体证明可以看题解):
1.弱双回文串 S S S的某个双回文划分 a b ab ab,满足 a a a S S S的最长回文前缀,或者 b b b S S S的最长回文后缀。
2.弱双回文串 S S S若有两个弱回文划分,则 S S S为整周期串。
3.弱双回文串 S S S的周期为 t t t,则其有 ∣ S ∣ t \frac{|S|}{t} tS个不同的弱回文划分。

我们先计算本质不同的双回文串划分,然后减去算重的。

首先考虑如何计算本质不同的双回文串划分,我们先正反建出两颗回文树,然后相当于是有 n − 1 n-1 n1个点对 ( a i , b i ) (a_i,b_i) (ai,bi),然后要统计合法的 ( c , d ) (c,d) (c,d),满足 a i a_i ai c c c的子树中且 b i b_i bi d d d的子树中,这个可以线段树合并+ O ( 1 ) O(1) O(1)lca做到 O ( n log ⁡ n ) O(n \log n) O(nlogn)统计。

然后考虑怎么减去算重的,一个双回文串 S S S被重复统计,则由 2 2 2得其为整周期串,假设其周期为 t t t,则会被多算 ∣ S ∣ t − 1 \frac{|S|}{t}-1 tS1 ∣ S ∣ t − 2 \frac{|S|}{t}-2 tS2次(分最小循环节是否为回文串讨论)。

这道题类似,由Runs Theorem,我们可以 O ( n log ⁡ n ) O(n \log n) O(nlogn)提取出所有的本原平方串,且本质不同的本原平方串只有 O ( n ) O(n) O(n)个,可以直接暴力+哈希存下来,这个时候我们发现对每个本原平方串只需存他最多被循环多少次就行了。

然后考虑对于每个本原平方串减去其算重的部分,首先如果他循环两次不是双回文串的话,那么这个本原平方串就没用了,具体怎么判断需要用性质 1 1 1。否则由性质 3 3 3,设其最多循环 p p p次,他会被重复计算 1 , 2 , 3 , . . . , p − 1 1,2,3,...,p-1 1,2,3,...,p1次(如果自己本身是回文串,则是 0 , 1 , 2 , . . . , p − 2 0,1,2,...,p-2 0,1,2,...,p2次),这个可以 O ( 1 ) O(1) O(1)计算。

可以发现,我们在 O ( n log ⁡ n ) O(n \log n) O(nlogn)的时间复杂度内解决了本题。

#include <bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace std;
typedef long long LL;
typedef pair <int,int> pii;

const int N=5e5+50, L=21;
int n,lg[N*2];
char ch[N];
LL ans;

struct PAM {
   
   
	int dep[N],fail[N],son[N]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值