码迷,mamicode.com
首页 > 其他好文 > 详细

JZYZOJ1369 [coci2012]覆盖字符串 AC自动机

时间:2017-11-05 19:15:08      阅读:153      评论:0      收藏:0      [点我收藏+]

标签: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 }
View Code

 

JZYZOJ1369 [coci2012]覆盖字符串 AC自动机

标签:math   getchar   pre   next   oid   去掉   print   size   fail   

原文地址:http://www.cnblogs.com/137shoebills/p/7788135.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!