字符串专题:后缀数组
后缀数组模板,复杂度:O(Nlog2n),用时要注意时间,这个比较耗时间
/* 后缀数组模板 asdfghjkl ghj 对两个串匹配 有ghj返回1 必须连续 */ #include<iostream> #include<cstring> #include<string> #include<cmath> #include<algorithm> using namespace std; int n,k; int rank[100005],tmp[100005],sa[100005]; bool common_sa(int i,int j) { if(rank[i]!=rank[j]) return rank[i]<rank[j]; else { int ri=i+k<=n?rank[i+k]:-1; int rj=j+k<=n?rank[i+k]:-1; return ri<rj; } } void construct_sa(string s,int *sa) { n=s.length(); for(int i=0;i<=n;i++) { sa[i]=i; rank[i]=i<n?s[i]:-1; } for(k=1;k<=n;k*=2) { sort(sa,sa+n+1,common_sa); tmp[sa[0]]=0; for(int i=1;i<=n;i++) { tmp[sa[i]]=tmp[sa[i-1]]+(common_sa(sa[i-1],sa[i])?1:0); } for(int i=0;i<=n;i++) { rank[i]=tmp[i]; } } } bool contain(string s,int *sa,string t) { int a=0,b=s.length(); while(b-a>1) { int c=(a+b)/2; if(s.compare(sa[c],t.length(),t)<0) a=c; else b=c; } return s.compare(sa[b],t.length(),t)==0; } int main() { string mode,donser; while(cin>>donser>>mode) { n=donser.size(); construct_sa(donser,sa); if(contain(donser,sa,mode)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }