正题

题目链接: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. javascript - 将字符串转换为模板字符串

    参考: https://www.itranslater.com/qa/details/2325714161562551296 是否可以将模板字符串创建为常用字符串 let a="b:${b} ...

  2. Data-truncation--Incorrect-string-value

    修改表中,format_content 字段的字符集为utf8mb4 alter table 表名 modify column format_content longtext character se ...

  3. 【ArcEngine】多用户同时编辑同一个版本数据的解决方法

    ArcMap或ArcEngine中,使用多个用户同时编辑default版本的时候,问题就来了,StopEditing 错误信息如下 FDO_E_VERSION_REDEFINED -214721714 ...

  4. pgsql学习

    --求所有人的薪水的总和,平均值,最大值,最小值 select sum(sal) , avg(sal), max(sal) , min(sal) from emp; --求总的行数 select co ...

  5. Linux的基础——虚拟机的克隆

    1.虚拟机的安装 虚拟机的安装在另一个文档 安装jdk(在另外一个文档中) 2.虚拟机的克隆 准备工作:一台装有Linux系统的主机(已经配置好jdk) 选择主机进行克隆 注意:这里一定要选择创建完整 ...

  6. SpringBoot应用中使用AOP记录接口访问日志

    SpringBoot应用中使用AOP记录接口访问日志 本文主要讲述AOP在mall项目中的应用,通过在controller层建一个切面来实现接口访问的统一日志记录. AOP AOP为Aspect Or ...

  7. MySQL binlog 自动清理脚本

    # vim /data/scripts/delete_mysql_binlog.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...

  8. 重启网络服务 network 出现问题

    2021-08-24 地址冲突了,因为想要设置成静态 ip 一直都不对,情急之下就将本地 ip 设置成了虚拟机的 ip,故出现此错误 后将地址改掉,重启网络服务就没有错误了 一开始我设置的虚拟网卡 n ...

  9. Mac automator bash 自动操作 右键菜单unrar解压 拷贝文件路径到剪贴板 快速删除(rm -rf) 快捷键设置

    https://tecadmin.net/pass-command-line-arguments-in-shell-script/ https://tecadmin.net/tutorial/bash ...

  10. 编程读写CAD文件验证

    背景 B/S应用系统,根据用户上传数据:业务数据和CAD坐标数据,经过一系列运筹算法运算后,输出一批坐标数据,作为给用户的规划结果.此时需要方便直观的给用户展示坐标数据.可选方式有两个: web页面画 ...