标签:math getchar pre next oid 去掉 print size fail
http://172.20.6.3/Problem_Show.asp?id=1369
trie树如果不优化就这么往里面放这么多单词肯定超空间+超时,所以需要去掉无用的字符串(不属于原字符串的),但是一个一个判断时间又很长;
所以解决方案就是用一个多维vis数组胡搞判定一下,非常魔性。。。
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const long long maxn=300010; 9 const int modn=10000; 10 int n,m; 11 char ch[maxn]={}; 12 char ch1[5010]={}; 13 int vis[maxn]={}; 14 queue<int>q; 15 struct trie{ 16 int next[26]; 17 bool exist; 18 int fail,d; 19 }e[maxn*4];int tot=0; 20 bool ff[26][26][26][26][26]={}; 21 void insert(int k,int d,int x){ 22 if(d==k){ 23 e[x].exist=1;e[x].d=d; 24 return; 25 } 26 int z=ch1[d]-‘a‘; 27 if(!e[x].next[z])e[x].next[z]=++tot; 28 insert(k,d+1,e[x].next[z]); 29 } 30 void build(){ 31 q.push(0);int x,y,f; 32 while(!q.empty()){ 33 x=q.front();q.pop(); 34 for(int i=0;i<26;i++){ 35 y=e[x].next[i]; 36 if(y){ 37 if(x!=0){ 38 f=e[x].fail; 39 while((!e[f].next[i])&&f)f=e[f].fail; 40 e[y].fail=e[f].next[i]; 41 }q.push(y); 42 } 43 } 44 } 45 } 46 int read(){ 47 char chh=getchar();int k=0; 48 while(chh<‘a‘||chh>‘z‘){chh=getchar();} 49 while(chh>=‘a‘&&chh<=‘z‘){ch1[k++]=chh;chh=getchar();} 50 return k; 51 } 52 void read1(){ 53 char chh=getchar();int k=0; 54 while(chh<‘a‘||chh>‘z‘){chh=getchar();} 55 while(chh>=‘a‘&&chh<=‘z‘){ch[k++]=chh;chh=getchar();} 56 } 57 int main(){ 58 //freopen("wtf.in","r",stdin); 59 //freopen("wtf.out","w",stdout); 60 scanf("%d",&n);read1(); 61 for(int i=4;i<n;i++){ 62 ff[(int)ch[i-4]-‘a‘][(int)ch[i-3]-‘a‘][(int)ch[i-2]-‘a‘][(int)ch[i-1]-‘a‘][(int)ch[i]-‘a‘]=1; 63 } 64 scanf("%d",&m); 65 for(int i=1;i<=m;i++){ 66 int siz=read(),wtf=1; 67 for(int j=4;j<siz;j++){ 68 if(!ff[(int)ch1[j-4]-‘a‘][(int)ch1[j-3]-‘a‘][(int)ch1[j-2]-‘a‘][(int)ch1[j-1]-‘a‘][(int)ch1[j]-‘a‘]) 69 wtf=0; 70 }if(wtf)insert(siz,0,0); 71 }build(); 72 int x=0,y; 73 for(int i=0;i<n;i++){ 74 int z=ch[i]-‘a‘; 75 while((!e[x].next[z])&&x){ 76 x=e[x].fail; 77 } 78 x=e[x].next[z];y=x; 79 while((!e[y].exist)&&y){ 80 y=e[y].fail; 81 }vis[i-e[y].d+1]=max(vis[i-e[y].d+1],e[y].d); 82 } 83 int k=0;int t=0; 84 for(int i=0;i<n;i++){ 85 k=max(vis[i],k); 86 if(k>0)t++; 87 k--; 88 } 89 printf("%d\n",n-t); 90 return 0; 91 }
JZYZOJ1369 [coci2012]覆盖字符串 AC自动机
标签:math getchar pre next oid 去掉 print size fail
原文地址:http://www.cnblogs.com/137shoebills/p/7788135.html