【51nod1006】simple KMP
原题意看的挺迷糊的,后来看了http://blog.csdn.net/YxuanwKeith/article/details/52351335大爷的题意感觉清楚的多……
做法也非常显然了,用树剖维护后缀自动机的parent树。
修改操作看成对每一个状态的right集合全都访问次数+1
询问同理。
然后我忘了更新爬后缀树时候的新状态调了挺久的。。。。。
因为这么傻逼的错误还能过样例。。。。。
#include<bits/stdc++.h>
const int N=2e5+;
const int yql=1e9+;
using namespace std;
int n,rt,tot=,head[N],cnt;
int size[N],wson[N],tpos[N],top[N],fa[N],d[N],len,pre[N];
char s[N];
struct Edge{int u,v,next;}G[N<<];
struct Suffix_AutoMaton{
int ch[N<<][],fa[N<<],l[N<<],cnt,last;
inline void init(){cnt=;last=;}
inline void ins(int c){
int p=last,np=++cnt;last=np;l[np]=l[p]+;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
if(!p)fa[np]=;
else{
int q=ch[p][c];
if(l[p]+==l[q])fa[np]=q;
else{
int nq=++cnt;l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];
fa[np]=fa[q]=nq;
for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
}
}
}
}sam;
inline void addedge(int u,int v){
G[++tot].u=u;G[tot].v=v;G[tot].next=head[u];head[u]=tot;
G[++tot].u=v;G[tot].v=u;G[tot].next=head[v];head[v]=tot;
}
inline void dfs1(int u,int f){
size[u]=;
for(int i=head[u];i;i=G[i].next){
int v=G[i].v;if(v==f)continue;
fa[v]=u;d[v]=d[u]+;
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[wson[u]])wson[u]=v;
}
}
inline void dfs2(int u,int tp){
tpos[u]=++cnt;pre[cnt]=u;top[u]=tp;
if(wson[u])dfs2(wson[u],tp);
for(int i=head[u];i;i=G[i].next){
int v=G[i].v;
if(v==fa[u]||v==wson[u])continue;
dfs2(v,v);
}
}
struct Segment_Tree{
#define lson (o<<1)
#define rson (o<<1|1)
int sumv[N<<],size[N<<],addv[N<<];
inline void pushup(int o){sumv[o]=(sumv[lson]+sumv[rson])%yql;}
inline void pushdown(int o,int l,int r){
if(!addv[o])return;
addv[lson]+=addv[o];addv[rson]+=addv[o];
sumv[lson]=(sumv[lson]+1LL*size[lson]*addv[o]%yql)%yql;
sumv[rson]=(sumv[rson]+1LL*size[rson]*addv[o]%yql)%yql;
addv[o]=;
}
inline void build(int o,int l,int r){
if(l==r){size[o]=sam.l[pre[l]]-sam.l[sam.fa[pre[l]]];return;}
int mid=(l+r)>>;
build(lson,l,mid);build(rson,mid+,r);
size[o]=(size[lson]+size[rson])%yql;
}
inline int querysum(int o,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return sumv[o];
int mid=(l+r)>>,ans=;
pushdown(o,l,r);
if(ql<=mid)ans=(ans+querysum(lson,l,mid,ql,qr))%yql;
if(qr>mid)ans=(ans+querysum(rson,mid+,r,ql,qr))%yql;
return ans;
}
inline void optadd(int o,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){addv[o]+=;if(addv[o]>yql)addv[o]-=yql;sumv[o]=(sumv[o]+size[o])%yql;return;}
int mid=(l+r)>>;pushdown(o,l,r);
if(ql<=mid)optadd(lson,l,mid,ql,qr);
if(qr>mid)optadd(rson,mid+,r,ql,qr);
pushup(o);
}
}T;
int main(){
scanf("%d",&n);
scanf("%s",s+);sam.init();
for(int i=;i<=n;i++)sam.ins(s[i]-'a');
for(int i=;i<=sam.cnt;i++)addedge(sam.fa[i],i);
dfs1(,);dfs2(,);T.build(,,sam.cnt);
int p=,ans=,cur=;
for(int i=;i<=n;i++){
int c=s[i]-'a';int u=sam.ch[p][c];
for(int j=u;j;j=fa[top[j]])cur=(cur+T.querysum(,,sam.cnt,tpos[top[j]],tpos[j]))%yql;
ans=(ans+cur)%yql;printf("%d\n",ans);
for(int j=u;j;j=fa[top[j]])T.optadd(,,sam.cnt,tpos[top[j]],tpos[j]);
p=u;
}
}
【51nod1006】simple KMP的更多相关文章
- P5410 【模板】扩展 KMP
P5410 [模板]扩展 KMP #include<bits/stdc++.h> using namespace std; ; int q, nxt[maxn], extend[maxn] ...
- 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)
题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...
- uoj #5. 【NOI2014】动物园 kmp
#5. [NOI2014]动物园 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/5 Description 近日 ...
- 【计数】Simple Addition Expression
[来源] 2008年哈尔滨区域赛 [题目链接]: http://acm.hdu.edu.cn/showproblem.php?pid=2451 [参考博客]: HDU 2451 Simple Addi ...
- 【POJ】【2601】Simple calculations
推公式/二分法 好题! 题解:http://blog.csdn.net/zck921031/article/details/7690288 这题明显是一个方程组……可以推公式推出来…… 然而这太繁琐了 ...
- 【数据结构】 字符串&KMP子串匹配算法
字符串 作为人机交互的途径,程序或多或少地肯定要需要处理文字信息.如何在计算机中抽象人类语言的信息就成为一个问题.字符串便是这个问题的答案.虽然从形式上来说,字符串可以算是线性表的一种,其数据储存区存 ...
- 【XSY2472】string KMP 期望DP
题目大意 给定一个由且仅由字符'H','T'构成的字符串\(S\). 给定一个最初为空的字符串\(T\) ,每次随机地在\(T\)的末尾添加'H'或者'T'. 问当\(S\)为\(T\)的后缀时, ...
- 【BZOJ3670】【NOI2014】动物园 [KMP][倍增]
动物园 Time Limit: 10 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description 近日,园长发现动物园中好吃懒做的动物 ...
- 【BZOJ3942】Censoring [KMP]
Censoring Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 有一个S串和一个T串,长 ...
随机推荐
- 【MediaElement】WPF视频播放器【3】
一.前言 对于<MediaElement>前两章介绍了差不多了,其实好的界面还需要UI工程师的配合,比如帮忙设计下按钮的样式等等.同样视频本身也需要吸引人,不然做的再好的播放器也没用.之后 ...
- Winform中的Treeview动态绑定数据库
http://bbs.csdn.net/topics/370139193 SQL code ? 1 2 3 4 5 6 CREATE TABLE [dbo].[Company] ( [Id ...
- HDU--2962
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2962 分析:最短路+二分. #include<iostream> #include< ...
- VC++的debug与release版本
因为在Debug中有ASSERT断言保护,所以要崩溃,而在Release优化中就会删掉ASSERT,所以会出现正常运行. void func() { char b[2]={0}; strc ...
- epoll的一些细节和注意事项
epoll_event结构 struct epoll_event { uint32_t events; /* Epoll events */ epoll_data_t data; /* User da ...
- 我学习的第一个uiautomator从创建到运行结束
一.新建自动化脚本 1.新建java工程包 [file]----[new]----[Java Project] 新建工程 [右 ...
- mysql database 格式的查看和改变
MySQL中,数据库的编码是一个相当重要的问题,有时候我们需要查看一下当前数据库的编码,甚至需要修改一下数据库编码. 查看当前数据库编码的SQL语句为: mysql> use xxx Datab ...
- 「Python」python与微信
pip3 install itchat 主要用到的方法: itchat.login() 微信扫描二维码登录 itchat.get_friends() 返回完整的好友列表,每个好友为一个字典, 其中第一 ...
- 调整的R方_如何选择回归模型
sklearn实战-乳腺癌细胞数据挖掘(博客主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&a ...
- XFire搭建WebService和客户端访问程序
开发环境:myeclipse8.6+jdk1.6.0_29+tomcat6.0.37 JAX-WS搭建webservice:http://www.cnblogs.com/gavinYang/p/352 ...