标签:编写 asi trie树 模板题 竞赛 cto 今天 span 暑假
今天主要将讲与字符串有关的吧。
1.trie树
Remember the Word(LA_3942)
trie树的模板题了。如果trie树不知道可以看蓝书(算法竞赛入门经典第一版)(以下的KMP和AC自动机都可以在此书上看到)。
#include<cstring> #include<vector> #include<cstdio> #include<iostream> using namespace std; const int mn=400010,mod=20071027;char ch[300010],w[101]; int T[mn][26],val[mn],sz=1,d[300010],len[4010],S,cnt=0; void add(char *s,int v){ int u=0,l=strlen(s); for(int i=0;i<l;i++){ int c=(int)(s[i]-‘a‘); if(!T[u][c]){ memset(T[sz],0,sizeof(T[sz])); val[sz]=0;T[u][c]=sz++; }u=T[u][c]; }val[u]=v; } void find(char *s,int len,vector<int>& ans){ int u=0;for(int i=0;i<len;i++){ if(s[i]==‘\0‘)break;int c=(int)(s[i]-‘a‘); if(!T[u][c])break;u=T[u][c]; if(val[u])ans.push_back(val[u]); } } int main(){ while(scanf("%s%d",ch,&S)!=EOF){ sz=1;memset(T[0],0,sizeof(T[0])); for(int i=1;i<=S;i++){scanf("%s",w);len[i]=strlen(w);add(w,i);} memset(d,0,sizeof(d));int l=strlen(ch);d[l]=1; for(int i=l-1;i>=0;i--){ vector<int>p;find(ch+i,l-i,p); for(int j=0;j<p.size();j++)d[i]=(d[i]+d[i+len[p[j]]])%mod; } printf("Case %d: %d\n",++cnt,d[0]); }return 0; }
2.KMP
这个算法比较难理解,但是很好记,效率O(n+m)。
Oulipo(poj_3461)
#include<cstring> #include<vector> #include<cstdio> #include<iostream> using namespace std; int f[10010],ans;char w[10010],t[1000010]; void getfail(){ f[0]=f[1]=0;int m=strlen(w); for(int i=1;i<m;i++){ int j=f[i]; while(j&&w[i]!=w[j])j=f[j]; f[i+1]=(w[i]==w[j]?j+1:0); } } void find(){ getfail();int j=0,n=strlen(t),m=strlen(w); for(int i=0;i<n;i++){ while(j&&w[j]!=t[i])j=f[j]; if(w[j]==t[i])j++;if(j==m)ans++; } } int main() { int n;scanf("%d",&n); while(n--){ memset(f,0,sizeof(f));ans=0; scanf("%s%s",w,t);find(); printf("%d\n",ans); } return 0; }
Period(poj_1961)
#include<cstring> #include<cstdio> #include<iostream> using namespace std; const int mk=1000010; char c[mk];int k,f[mk],cnt=0; void getfail(){ f[0]=f[1]=0; for(int i=1;i<k;i++){ int j=f[i]; while(j&&c[i]!=c[j])j=f[j]; f[i+1]=(c[i]==c[j]?j+1:0); } } int main() { scanf("%d",&k); while(k){ scanf("%s",c); getfail();printf("Test case #%d\n",++cnt); for(int i=2;i<=k;i++) if(f[i]&&i%(i-f[i])==0) printf("%d %d\n",i,i/(i-f[i])); puts("");scanf("%d",&k); } return 0; }
Power Strings(poj_2406)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=1000010; int f[N],k;char c[N]; void getfail(){ f[0]=f[1]=0; for(int i=1;i<k;i++){ int j=f[i]; while(j&&c[i]!=c[j])j=f[j]; f[i+1]=(c[i]==c[j]?j+1:0); } } int main() { while(1){ scanf("%s",c); if(c[0]==‘.‘)break; k=strlen(c);getfail(); if(f[k]&&k%(k-f[k])==0)printf("%d\n",k/(k-f[k])); else puts("1"); } return 0; }
3.AC自动机(aho-corasick自动机)
本算法是结合了以上的trie树和KMP算法。
(暂缺)。
本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。
标签:编写 asi trie树 模板题 竞赛 cto 今天 span 暑假
原文地址:http://www.cnblogs.com/Yzyet/p/7143274.html