日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

2019.03.01 bzoj2555: SubString(sam+lct)

發布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2019.03.01 bzoj2555: SubString(sam+lct) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傳送門
題意簡述:
要求在線支持兩個操作
(1):在當前字符串的后面插入一個字符串
(2):詢問字符串s在當前字符串中出現了幾次?(作為連續子串)


思路:
考慮用lctlctlct來動態維護samsamsamrightrightright集合。
代碼:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=1200005;
char s[N];
int n;
string str;
inline void gets(int Mask){scanf("%s",s);str=s;for(ri i=0,up=str.size();i<up;++i){Mask=(Mask*131+i)%up;char t=str[i];str[i]=str[Mask];str[Mask]=t;}
}
int Mask=0;
namespace lct{int son[N][2],rev[N],siz[N],fa[N],add[N],stk[N],top=0;inline void pushnow(int p,int v){siz[p]+=v,add[p]+=v;}inline void pushdown(int p){if(add[p])pushnow(son[p][0],add[p]),pushnow(son[p][1],add[p]),add[p]=0;}inline bool isroot(int p){return !fa[p]||((p^son[fa[p]][0])&&(p^son[fa[p]][1]));}inline bool which(int p){return p^son[fa[p]][0];}inline void rotate(int x){int y=fa[x],z=fa[y],t=which(x);if(z&&!isroot(y))son[z][which(y)]=x;fa[y]=x,fa[x]=z,son[y][t]=son[x][t^1],son[x][t^1]=y;if(son[y][t])fa[son[y][t]]=y;}inline void splay(int x){stk[top=1]=x;for(ri p=x;!isroot(p);p=fa[p])stk[++top]=fa[p];while(top)pushdown(stk[top--]);	while(!isroot(x)){if(!isroot(fa[x]))rotate(which(x)^which(fa[x])?x:fa[x]);rotate(x);}}inline void access(int x){for(ri y=0;x;x=fa[y=x])splay(x),son[x][1]=y;}inline void link(int x,int y){fa[x]=y,access(y),splay(y),pushnow(y,siz[x]);}inline void cut(int x){access(x),splay(x),pushnow(son[x][0],-siz[x]),fa[son[x][0]]=0,son[x][0]=0;}
}
namespace sam{int son[N][26],len[N],Link[N],tot=1,last=1;inline void insert(int x){int p=last,np=++tot;lct::siz[np]=1,len[last=np]=len[p]+1;while(p&&!son[p][x])son[p][x]=np,p=Link[p];if(!p)return lct::link(np,Link[np]=1);int q=son[p][x],nq;if(len[q]==len[p]+1)return lct::link(np,Link[np]=q);len[nq=++tot]=len[p]+1,memcpy(son[nq],son[q],sizeof(son[nq]));lct::link(nq,Link[nq]=Link[q]);lct::cut(q);lct::link(np,Link[np]=nq);lct::link(q,Link[q]=nq);while(p&&son[p][x]==q)son[p][x]=nq,p=Link[p];}inline void init(){scanf("%s",s+1);for(ri i=1,up=strlen(s+1);i<=up;++i)insert(s[i]-'A');}inline void add(){gets(Mask);for(ri i=0,up=str.size();i<up;++i)insert(str[i]-'A');}inline int query(){gets(Mask);int p=1;for(ri i=0,up=str.size();i<up;++i)if(!(p=son[p][str[i]-'A']))return 0;return lct::splay(p),lct::siz[p];}
}
int main(){scanf("%d",&n),sam::init();while(n--){char op[6];scanf("%s",op);if(op[0]=='A')sam::add();else{int ret=sam::query();Mask^=ret,cout<<ret<<'\n';}}
}

轉載于:https://www.cnblogs.com/ldxcaicai/p/10582388.html

總結

以上是生活随笔為你收集整理的2019.03.01 bzoj2555: SubString(sam+lct)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。