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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字符串(AC自动机(fail tree))

發布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字符串(AC自动机(fail tree)) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傳送門

注意:注釋中的那段代碼是不能用的

#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> using namespace std; typedef long long ll; const int N=2000010; struct Edge{int v,nxt;}edge[N]; int head[N],cnt; int ch[N][26],fail[N],word[N],num; int st[N],ed[N],tot; int m,l,len[N],bg[N],que,work[N]; ll c[N],mask,ans,val[N],opt[N]; char s[N],str[N]; void add_edge(int u,int v){edge[++cnt].v=v;edge[cnt].nxt=head[u];head[u]=cnt; } void insert(char *s,int id){int now=0;for(int i=0;i<len[id];i++){int x=s[i]-'a';if(!ch[now][x]) ch[now][x]=++num;now=ch[now][x];}word[id]=now; } void get_fail(){queue<int> q;for(int i=0;i<26;i++){if(ch[0][i]) q.push(ch[0][i]);}while(!q.empty()){int now=q.front();q.pop();for(int i=0;i<26;i++){if(ch[now][i]){fail[ch[now][i]]=ch[fail[now]][i];q.push(ch[now][i]);}else ch[now][i]=ch[fail[now]][i];}} } void dfs(int u){st[u]=++tot;for(int i=head[u];i;i=edge[i].nxt) dfs(edge[i].v);ed[u]=tot; } void build_fail_tree(){for(int i=1;i<=num;i++)add_edge(fail[i],i);dfs(0); } inline int lowbit(int x){return x&(-x);} void add(int x,int d){for(int i=x;i<=tot;i+=lowbit(i))c[i]+=d; } ll getsum(int x){ll sum=0;for(int i=x;i>=1;i-=lowbit(i))sum+=c[i];return sum; } void query(int l,int r){que++;int now=0;for(int i=l;i<=r;i++){now=ch[now][s[i]-'a'];if(work[now]==que)//子串在s中已經出現過 ans+=val[now];else{work[now]=que;//val[now]=getsum(ed[now])-getsum(st[now]-1);val[now]=getsum(st[now]);ans+=val[now];}} } int main(){scanf("%d",&m);for(int i=1;i<=m;i++){scanf("%lld%s",&opt[i],str);len[i]=strlen(str);bg[i]=l+1;insert(str,i);for(int j=0;j<len[i];j++)s[++l]=str[j];}get_fail();build_fail_tree();for(int i=1;i<=m;i++){opt[i]^=mask;if(opt[i]==1){add(st[word[i]],1);add(ed[word[i]]+1,-1);} //add(st[word[i]],1);else if(opt[i]==2){add(st[word[i]],-1);add(ed[word[i]]+1,1);} //add(st[word[i]],-1);else if(opt[i]==3){ans=0;query(bg[i],bg[i]+len[i]-1);printf("%lld\n",ans);mask^=labs(ans);}}return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的字符串(AC自动机(fail tree))的全部內容,希望文章能夠幫你解決所遇到的問題。

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