正题

题目链接:https://www.luogu.com.cn/problem/P5287


题目大意

开始一个空串,\(n\)个操作

  1. 在末尾加入\(x\)个\(c\)字符(保证和\(c\)和前面的字符不同)
  2. 返回到第\(x\)次操作之后

每次操作完成后求所有前缀的最长的\(border\)长度和

\(1\leq n\leq 10^5\)


解题思路

二操作好像是一个离线树能搞出来的先只考虑一操作,因为是相当于求\(kmp\)之后的\(next\)和,所以可以考虑一下用\(kmp\)。

每个插入操作我们可以看做插入了一个二元组\((c,x)\),\(nxt_i\)表示按照二元组完全匹配来KMP的\(next\)数组。

然后求答案的时候设现在这个二元组\((c,x)\),已经匹配到\(now\)个\(c\),然后往前跳\(nxt\)的时候如果下一个二元组的字符是\(c\)且数量\(x>now\)那么我们就往后计算答案然后让\(now=x\)。

然后最后剩下的一些如果能和第一个匹配就全都匹配。

然后这样跑是能过的,但是加了二操作之后就会\(T\),因为KMP是均摊复杂度的,会被\(hack\)。

所以考虑一下怎么优化,我们知道\(broder\)可以被划分成\(log\)个等差数列,而且一定是按照长度来排列的,如果我们发现我们跳进了一个无法匹配的等差数列中我们就直接跳到这个等差数列结束的位置因为这个等差数列中已经不能匹配了。

这样复杂度就到了\(O(n\log n)\)了


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
const ll N=1e5+10,P=998244353;
ll n,len,ch[N][2],s[N][3],ans[N],nxt[N],prt[N],p[N];
vector<ll> e[N];
ll gs(ll l,ll r)
{return (r+l)*(r-l+1)/2;}
void dfs(ll x){
ll i=nxt[len++];
s[len][0]=ch[x][0];
s[len][1]=ch[x][1];
s[len][2]=s[len-1][2]+ch[x][1];
ans[len]=ans[len-1];nxt[len]=0;
if(len==1){ans[len]=gs(1,ch[x][1]-1);}
else{
ll d=len-i;
while(i&&(s[i+1][0]!=ch[x][0]||s[i+1][1]!=ch[x][1])){
if(i-nxt[i]==d)i=i%d+d;
d=i-nxt[i];i=nxt[i];
}
nxt[len]=i+(i||(ch[x][0]==s[1][0]&&ch[x][1]>=s[1][1]));
ll now=0;i=nxt[len-1],d=len-1-i;
while(now<ch[x][1]&&i){
if(s[i+1][0]==ch[x][0]&&s[i+1][1]>now){
ans[len]+=gs(s[i][2]+now+1,s[i][2]+min(ch[x][1],s[i+1][1]));
now=s[i+1][1];
}
if(i-nxt[i]==d)i=i%d+d;
d=i-nxt[i];i=nxt[i];
}
if(now<ch[x][1]&&s[1][0]==ch[x][0]){
if(s[i+1][1]>now)ans[len]+=gs(now+1,min(ch[x][1],s[i+1][1]));
now=max(now,min(ch[x][1],s[i+1][1]));
ans[len]+=s[1][1]*(ch[x][1]-now);
}
}
prt[x]=ans[len];
for(ll i=0;i<e[x].size();i++)
dfs(e[x][i]);
len--;return;
}
signed main()
{
scanf("%lld",&n);
for(ll i=1;i<=n;i++){
ll op;scanf("%lld ",&op);
if(op==1){
scanf("%lld %c",&ch[i][1],&ch[i][0]);
e[p[i-1]].push_back(p[i]=i);
}
else{
ll x;scanf("%lld",&x);
p[i]=p[x];
}
}
for(ll i=0;i<e[0].size();i++)
dfs(e[0][i]);
for(ll i=1;i<=n;i++)
printf("%lld\n",prt[p[i]]%P);
return 0;
}

P5287-[HNOI2019]JOJO【KMP】的更多相关文章

  1. 【KMP】【最小表示法】NCPC 2014 H clock pictures

    题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1794 题目大意: 两个无刻度的钟面,每个上面有N根针(N<=200000),每个 ...

  2. 【动态规划】【KMP】HDU 5763 Another Meaning

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5763 题目大意: T组数据,给两个字符串s1,s2(len<=100000),s2可以被解读成 ...

  3. HDOJ 2203 亲和串 【KMP】

    HDOJ 2203 亲和串 [KMP] Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...

  4. 【KMP】Censoring

    [KMP]Censoring 题目描述 Farmer John has purchased a subscription to Good Hooveskeeping magazine for his ...

  5. 【KMP】OKR-Periods of Words

    [KMP]OKR-Periods of Words 题目描述 串是有限个小写字符的序列,特别的,一个空序列也可以是一个串.一个串P是串A的前缀,当且仅当存在串B,使得A=PB.如果P≠A并且P不是一个 ...

  6. 【KMP】Radio Transmission

    问题 L: [KMP]Radio Transmission 题目描述 给你一个字符串,它是由某个字符串不断自我连接形成的.但是这个字符串是不确定的,现在只想知道它的最短长度是多少. 输入 第一行给出字 ...

  7. 【kmp】似乎在梦中见过的样子

    参考博客: BZOJ 3620: 似乎在梦中见过的样子 [KMP]似乎在梦中见过的样子 题目描述 「Madoka,不要相信QB!」伴随着Homura的失望地喊叫,Madoka与QB签订了契约. 这是M ...

  8. 【POJ2752】【KMP】Seek the Name, Seek the Fame

    Description The little cat is so famous, that many couples tramp over hill and dale to Byteland, and ...

  9. 【POJ2406】【KMP】Power Strings

    Description Given two strings a and b we define a*b to be their concatenation. For example, if a = & ...

随机推荐

  1. maven打jar包,导入本地jar

    本地jar包存放目录 项目目录/lib/*.jar 导入jar包配置 <resources> <!--扫描到的配置yml--> <resource> <dir ...

  2. tcp为什么要三次握手,tcp为什么可靠

    转自 : https://www.cnblogs.com/LUO77/p/5771237.html大体看过,没有深入研究,有需要时继续看. 为什么不能两次握手:(防止已失效的连接请求又传送到服务器端, ...

  3. uwp 的锁屏功能

    [UWP开发]自定义锁屏&桌面壁纸 mtobeiyf关注 2015.11.01 00:16:55字数 394阅读 1,249 调用通用的API来设置桌面壁纸,可以实现很多有趣的功能.在Wind ...

  4. 统计MySQL数据库硬盘占用量大小

    select TABLE_NAME, concat(truncate(data_length/1024/1024,2),' MB') as data_size, concat(truncate(ind ...

  5. Mysql慢查询explain

    转自:https://www.toutiao.com/i6776461352522220036/?tt_from=weixin&utm_campaign=client_share&wx ...

  6. 利用AOP切面打印项目中每个接口的运行情况

    1.前言 AOP切面技术,大家应该都听知道,Spring框架的主要功能之一. AOP切面的用途很广,其中一个常见的用途就是打印接口方法的运行日志和运行时间. 日志对于一个项目很是重要,不仅有助于调错, ...

  7. spring-data-redis 动态切换数据源

    最近遇到了一个麻烦的需求,我们需要一个微服务应用同时访问两个不同的 Redis 集群.一般我们不会这么使用 Redis,但是这两个 Redis 本来是不同业务集群,现在需要一个微服务同时访问. 其实我 ...

  8. ajax无法返回视图

    $.ajax({ url:"http://localhost:8080/wb/toUpLoad", type:"post", data:formData, pr ...

  9. windows下mysql5.7.17配置

    1.官网下载mysql5.7.17 64位 https://dev.mysql.com/downloads/mysql/ 2.安装完解压到E盘主目录下,改文件名为mysql 3.配置环境变量 我的电脑 ...

  10. PyQT5基础布局管理

    绝对定位布局 使用move(x, y)可以对窗口进行布局,以窗口左上角为原点,向右为 x 轴正方向,向下为 y 轴正方向,移动(x,y); import sys from PyQt5.QtGui im ...