1 条题解
-
0
自动搬运
来自洛谷,原作者为

SpadeA261
**搬运于
2025-08-24 22:51:31,当前版本为作者最后更新于2023-10-30 01:42:54,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
写一种考场上想到的线性做法。
根据性质,若 与 均为合法子串,那么 必为合法子串。
考虑 dp,设 表示以第 位作为结尾的合法子串数量,容易得出转移方程:,其中 表示最大且能使 成为合法子串的下标。答案即为 。
由于 是满足条件中最大的,因此必有 ,我们就可以按下图的方式从 往前跳,初始时 ,之后不断令 ,直到满足 。

该做法的时间复杂度为 ,足以通过本题。考虑如何更进一步优化。
如果令 ,会发现跳的方式变成了这样,形成了若干条链,由此在每个位置记录 ,表示 且能使 成为合法子串的最大的下标。

每次修改的值只有 ,我们便可以用 表示该链的链头,每次修改 即可。
时间复杂度:。
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=2e6+5; int n,dp[N],a[N][26],to[N]; char s[N]; ll ans; int main() { scanf("%d%s",&n,s+1); for(int i=1;i<=n;i++) { to[i]=i; int x=a[to[i-1]][s[i]-'a']; if(x) to[i]=to[x-1],dp[i]=dp[x-1]+1; a[to[i]][s[i]-'a']=i,ans+=dp[i]; } printf("%lld\n",ans); return 0; }
- 1
信息
- ID
- 9311
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者