一道神仙题,考察选手对KMP的深入理解。

先考虑没有2操作的做法。设每一段为一个二元组(x,c),考虑一段前缀匹配后缀,除了第一段的字符,其他段的二元组(x,c)必须相等,所以可以将其视为特殊字符进行匹配。在串末尾加入(x,c)时,显然不断跳next数组,如果当前前缀后接的字符为c ,那么可以增加一段首项为当前前缀长度,然后发现这一段的next数组为首项为前缀长度,公差为1的等差数列。next链上如果有等于(x,c)的二元组,则next指向二元组,否则指向0,因为如果存在(y,c)满足y>x,则一定无法匹配。

解决了没有2操作的做法,考虑有2操作,由于KMP复杂度是均摊的,很显然不能直接在树上dfs,所以要优化求next过程。考虑离线建树,dfs时维护每条next链上的KMP自动机,f[i][j][k]表示状态i下加入二元组(j,k)next指向哪,g[i][j][k]表示产生的贡献,每次修改复制前一次的f数组,修改f[i][x][c],g[i][x][1...c]为等差数列,此处可以用主席树实现。

#include<bits/stdc++.h>
#define lson l,mid,tr[rt].lc
#define rson mid+1,r,tr[rt].rc
using namespace std;
const int N=1e5+10,M=1e4+7,mod=998244353;
struct node{int lc,rc,sum,lazy,nxt;}tr[N*60];
int n,tot,top,val[N],pos[N],ans[N],a[N],b[N],rt[N][26],mx[N][26];
vector<int>G[N];
void newnode(int&x){tr[++tot]=tr[x],x=tot;}
void add(int x,int v,int len){tr[x].sum=1ll*v*len%mod,tr[x].lazy=v;}
int S(int x){return 1ll*x*(x+1)/2%mod;}
void pushdown(int l,int r,int rt)
{if(!tr[rt].lazy)return;int mid=l+r>>1;newnode(tr[rt].lc),add(tr[rt].lc,tr[rt].lazy,mid-l+1);newnode(tr[rt].rc),add(tr[rt].rc,tr[rt].lazy,r-mid);tr[rt].lazy=0;
}
void update(int k,int v,int p,int l,int r,int&rt)
{newnode(rt);if(r<k){add(rt,v,r-l+1);return;}if(l==r){tr[rt].nxt=p,add(rt,v,1);return;}pushdown(l,r,rt);int mid=l+r>>1;update(k,v,p,lson);if(k>mid)update(k,v,p,rson);tr[rt].sum=(tr[tr[rt].lc].sum+tr[tr[rt].rc].sum)%mod;
}
void query(int k,int&ans,int&nxt,int l,int r,int&rt)
{if(r<k){ans=(ans+tr[rt].sum)%mod;return;}if(l==r){ans=(ans+tr[rt].sum)%mod,nxt=tr[rt].nxt;return;}pushdown(l,r,rt);int mid=l+r>>1;query(k,ans,nxt,lson);if(k>mid)query(k,ans,nxt,rson);
}
void dfs(int u)
{++top;int x=val[u]/M,y=val[u]%M,nxt=0;a[top]=val[u],b[top]=b[top-1]+y;if(top==1)ans[u]=S(y-1);else{ans[u]=(ans[u]+S(min(mx[top][x],y)))%mod;query(y,ans[u],nxt,1,M,rt[top][x]);if(!nxt&&a[1]/M==x&&b[1]<y)nxt=1,ans[u]=(ans[u]+1ll*b[1]*max(0,y-mx[top][x]))%mod;}mx[top][x]=max(mx[top][x],y);update(y,b[top-1],top,1,M,rt[top][x]);for(int i=0;i<G[u].size();i++){memcpy(mx[top+1],mx[nxt+1],sizeof mx[top+1]);memcpy(rt[top+1],rt[nxt+1],sizeof rt[top+1]);ans[G[u][i]]=ans[u],dfs(G[u][i]);}--top;
}
int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){int op,x;scanf("%d%d",&op,&x);if(op==1){char c;cin>>c;val[++tot]=(c-'a')*M+x,pos[i]=tot,G[pos[i-1]].push_back(pos[i]);}else pos[i]=pos[x];}for(int i=0;i<G[0].size();i++){tot=0;memset(rt[1],0,sizeof rt[1]);memset(mx[1],0,sizeof mx[1]);dfs(G[0][i]);}for(int i=1;i<=n;i++)printf("%d\n",ans[pos[i]]);
}

View Code

转载于:https://www.cnblogs.com/hfctf0210/p/10801699.html

[HNOI2019]JOJO(KMP自动机+主席树)相关推荐

  1. LOJ 3055 「HNOI2019」JOJO—— kmp自动机+主席树

    题目:https://loj.ac/problem/3055 先写了暴力.本来想的是 n<=300 的那个在树上暴力维护好整个字符串, x=1 的那个用主席树维护好字符串和 nxt 数组.但 x ...

  2. 【SAM套路/AC自动机+主席树】CF547E Mike and Friends

    [题目] CF 给定 n n n个串 a i a_i ai​, Q Q Q组询问 a l ∼ a r a_l\sim a_r al​∼ar​中 a x a_{x} ax​出现了多少次. ∑ ∣ a i ...

  3. BZOJ 3277 串 BZOJ 3473 字符串 (广义后缀自动机、时间复杂度分析、启发式合并、线段树合并、主席树)...

    标签那么长是因为做法太多了... 题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277 (bzoj 3473) ...

  4. HDU - 7084 Pty loves string kmp + fail树 + 主席树

    传送门 文章目录 题意: 思路: 题意: 给你一个字符串sss,有qqq个询问,每次给x,yx,yx,y代表取sss的前xxx个字符和后yyy个字符拼接起来得到ttt,输出ttt在sss中出现的次数. ...

  5. [HNOI2019]JOJO

    不错的好题 有一个比较弱化的问题: [题集]串 已知小串的子串问题,例题2 本题: 首先单纯快速跳kmp就要用到AC自动机的fail了(单串AC自动机) 所谓回撤,就是一个可持久化, 建出时间树,直接 ...

  6. BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)

    吐槽: 为啥很多人用AC自动机暴力跳都过了?复杂度真的对么? 做法一: AC自动机+树状数组 姓名的问题,中间加个特殊字符连起来即可. 肯定是对点名串建AC自动机(map存儿子),然后第一问就相当于问 ...

  7. HDU - 6704 K-th occurrence (后缀数组+主席树)

    题目链接 题意 QQQ次询问,每次询问求SSS的子串出现KKK次的位置 思路 刚开始想的是AC自动机,但是建自动机会超时,后来学长想到后缀数组+主席树的做法Orz...Orz...Orz... 出现K ...

  8. hdu 2665(主席树查询区间k大值)

    先贴我自己写的代码做模板虽然跟原博主没什么两样.(一开始空间开的4*maxn,交到hdu上一直TLE很奇怪) #include<bits/stdc++.h> using namespace ...

  9. P3168 [CQOI2015]任务查询系统 差分+主席树

    链接在这~:https://www.luogu.org/problem/P3168 主席静态区间修改,单点查询 区间(L,R)加1可以通过差分以后转换为L位置加1,R+1位置减1 我们只需要记录一下, ...

  10. 洛谷 P3302 [SDOI2013]森林 主席树+启发式合并

    click here~:https://www.luogu.org/problem/P3302 emmm这个题是真的烦 一看题发现这题不是count on a tree的升级版么 如果一点思路没有的话 ...

最新文章

  1. 使用LitePal操作数据库(CRUD增删改查) 项目已上传GitHub
  2. ABAP高级顾问应该掌握的技术
  3. Linux发行版 (列表)
  4. 深入解读Gartner 2021年《分析与BI平台魔力象限》
  5. EL表达式及其定义和使用 转
  6. 电大计算机dm编写程序,渭南电大计算机应用基础网考答题过程介绍
  7. 计算机教师招聘试题(汇总集合版),计算机教师招聘试题(汇总集合版).doc
  8. 基于java+SpringBoot+HTML+Mysq幼儿园日常管理系统
  9. 如何在虚拟机linux下运行程序吗,在Linux上运行虚拟机的3种方法 | MOS86
  10. 【安装配置】SAS9.4安装
  11. 面向计算机视觉的深度学习 | iBooker·ApacheCN
  12. 华为U2000客户端安装过程
  13. 如何在生化实验中选择合适的牛血清白蛋白(BSA)?
  14. 用java写新年快乐特效代码_蓝叶分享新年快乐大红灯笼特效代码
  15. java记忆翻牌,原生JS实现记忆翻牌游戏
  16. 关于基本勾股数规律的探讨总结与例题!
  17. Python实现psf2otf
  18. 【DBA100人】胡中豪:国产分布式数据库DBA炼成记
  19. 图数据分析到图卷积神经网络
  20. java webshell_都0202年了老嗨还在用的 - 各种姿势jsp webshell

热门文章

  1. python 科研统计_Python科研统计作图Plotnine+Seaborn+matplotlib替代R ggplot2系列!(二)...
  2. vs2015 ef 连接mysql_VS2015 + EF6连接MYSQL
  3. tomcat日志打印乱码
  4. freebsd mysql utf8_FreeBSD环境下Mysql问题解决方法集锦
  5. 修改sqlserver编码为utf8_修改Matlab默认编码格式为UTF-8
  6. Tensorflow笔记:MNIST数据集输出手写数字识别准确率
  7. Kubernetes Jobs - 运行处理任务指南
  8. openSUSE 安装 Torch
  9. BZOJ1114 : [POI2008]鲁滨逊逃生Rob
  10. 团队作业三——项目思考