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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P5212-SubString【LCT,SAM】

發(fā)布時間:2023/12/3 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P5212-SubString【LCT,SAM】 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.com.cn/problem/P5212


題目大意

開始一個字符串SSS,有nnn次操作

  • SSS末尾加入一個字符串
  • 詢問一個串在SSS中出現(xiàn)了多少次
  • 強(qiáng)制在線


    解題思路

    強(qiáng)制在線的話,只有SAM\text{SAM}SAM能夠支持動態(tài)插字符了,但是我們平時統(tǒng)計(jì)答案的時候要先做一次拓?fù)渑判蛉缓笊蟼餍畔ⅰ?/p>

    這里要動態(tài)維護(hù)parents\text{parents}parents樹的話用LCT\text{LCT}LCT就好了,就是鏈修改加單點(diǎn)查詢,然后因?yàn)楦侵付ǖ目梢陨賹懞芏嗖僮鳌?/p>

    時間復(fù)雜度O((n+S)log?∣S∣)O(\ (n+S)\log |S|)O(?(n+S)logS)


    code

    #include<cstdio> #include<cstring> #include<algorithm> #include<stack> using namespace std; const int N=6e5*2+10; int n,cnt,len[N],fa[N],ch[N][26]; char st[N]; struct LCT{int t[N][2],lazy[N],w[N],fa[N];stack<int> s;bool Nroot(int x){return fa[x]&&((t[fa[x]][0]==x)||(t[fa[x]][1]==x));}bool Direct(int x){return t[fa[x]][1]==x;}void Add(int x,int val){if(x)w[x]+=val,lazy[x]+=val;return;}void PushDown(int x){if(!lazy[x])return;if(t[x][0])Add(t[x][0],lazy[x]);if(t[x][1])Add(t[x][1],lazy[x]);lazy[x]=0;return;}void Rotate(int x){int y=fa[x],z=fa[y];int xs=Direct(x),ys=Direct(y);int w=t[x][xs^1];if(Nroot(y))t[z][ys]=x;t[y][xs]=w;t[x][xs^1]=y;if(w)fa[w]=y;fa[y]=x;fa[x]=z;return;}void Splay(int x){int y=x;s.push(x);while(Nroot(y))y=fa[y],s.push(y);while(!s.empty())PushDown(s.top()),s.pop();while(Nroot(x)){y=fa[x];if(!Nroot(y))Rotate(x);else if(Direct(y)==Direct(x))Rotate(y),Rotate(x);else Rotate(x),Rotate(x);}return;}void Access(int x){for(int y=0;x;y=x,x=fa[x])Splay(x),t[x][1]=y;return;}void Link(int x,int y)//x為單點(diǎn),y為樹{fa[x]=y;Access(y);Splay(y);Add(y,w[x]);return;}void Cut(int x)//將x切斷為單點(diǎn){Access(x);Splay(x);Add(t[x][0],-w[x]);fa[t[x][0]]=0;t[x][0]=0;return;} }T; void decode(char *s,int l,int mask) {for (int j=0;j<l;j++) {mask=(mask*131+j)%l;swap(s[j],s[mask]);}return; } int insert(int c,int p){int np=++cnt;len[np]=len[p]+1;T.w[np]++;for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;if(!p)fa[np]=1,T.Link(np,1);else{int q=ch[p][c];if(len[p]+1==len[q])fa[np]=q,T.Link(np,q);else{int nq=++cnt;len[nq]=len[p]+1;memcpy(ch[nq],ch[q],sizeof(ch[nq]));fa[nq]=fa[q];fa[np]=fa[q]=nq;T.Cut(q);T.Link(nq,fa[nq]);T.Link(np,nq);T.Link(q,nq);for(;p&&ch[p][c]==q;p=fa[p])ch[p][c]=nq;}}return np; } int main() {scanf("%d",&n);scanf("%s",st);int l=strlen(st);int p=cnt=1;int mask=0;for(int i=0;i<l;i++)p=insert(st[i]-'A',p);while(n--){char op[5];scanf("%s %s",op,st);l=strlen(st);decode(st,l,mask);if(op[0]=='Q'){int x=1;for(int i=0;i<l;i++)if(!ch[x][st[i]-'A']){x=0;break;}else x=ch[x][st[i]-'A'];if(!x)puts("0");else{T.Splay(x);printf("%d\n",T.w[x]);mask^=T.w[x];}}else{for(int i=0;i<l;i++)p=insert(st[i]-'A',p);}}return 0; }

    總結(jié)

    以上是生活随笔為你收集整理的P5212-SubString【LCT,SAM】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。