字符串(AC自动机):COCI 2015 round 5 divljak

 

 

题目点这里,最后一题

  

  不用bit的话最大数据2.8s,超时,有些遗憾,代码如下:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <queue>
 6 using namespace std;
 7 const int N=2000010;
 8 int n,Q,cnt,len,x,tp,top,st[N],vis[N],tim;
 9 int ch[N][26],fail[N],num[N],id[N];
10 char s[N];queue<int>q;
11 int main(){
12     freopen("divljak.in","r",stdin);
13     freopen("divljak.out","w",stdout);
14     ios::sync_with_stdio(false);
15     cin.tie(NULL),cout.tie(NULL);
16     cin>>n;
17     for(int t=1;t<=n;t++){
18         cin>>s;
19         len=strlen(s);int p=0;
20         for(int i=0;i<len;i++)
21             if(ch[p][s[i]-'a'])
22                 p=ch[p][s[i]-'a'];
23             else
24                 p=ch[p][s[i]-'a']=++cnt;
25         id[t]=p;            
26     }
27     for(int i=0;i<26;i++)
28         if(ch[0][i])q.push(ch[0][i]);
29     
30     while(!q.empty()){
31         int x=q.front();q.pop();
32         for(int i=0;i<26;i++)
33             if(ch[x][i])fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
34             else ch[x][i]=ch[fail[x]][i];
35     }
36     cin>>Q;
37     while(Q--){
38         cin>>tp;
39         if(tp==1){
40             cin>>s;top=0;
41             len=strlen(s);int p=0;++tim;
42             for(int i=0;i<len;i++){
43                 while(p&&!ch[p][s[i]-'a'])p=fail[p];p=ch[p][s[i]-'a'];
44                 int tmp=p;while(tmp&&vis[tmp]!=tim)vis[st[++top]=tmp]=tim,tmp=fail[tmp];
45             }
46             sort(st+1,st+top+1);
47             top=unique(st+1,st+top+1)-st-1;
48             for(int i=1;i<=top;i++)num[st[i]]+=1;
49         }
50         else{
51             cin>>x;
52             cout<<num[id[x]]<<"\n";
53         }
54     }
55     return 0;
56 }

  然后我的标解超时了?

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <queue>
  6 using namespace std;
  7 const int N=2000010;
  8 int n,Q,cnt,len,x,tp,top,st[N];
  9 int ch[N][26],fail[N],num[N],pd[N];
 10 int bit[N],fa[N][22],id[N],ed[N],tot;
 11 int cntE,nxt[N],to[N],fir[N],dep[N];
 12 char s[N];queue<int>q;
 13 
 14 void addedge(int a,int b){
 15     nxt[++cntE]=fir[a];
 16     to[fir[a]=cntE]=b;
 17 }
 18 
 19 void DFS(int x,int f){
 20     id[x]=++tot;dep[x]=dep[f]+1;
 21     for(int i=fir[x];i;i=nxt[i])
 22         fa[to[i]][0]=x,DFS(to[i],x);
 23     ed[x]=tot;
 24 }
 25 
 26 int Lca(int x,int y){
 27     if(dep[x]<dep[y])swap(x,y);
 28     int d=dep[x]-dep[y];
 29     for(int i=21;i>=0;i--)
 30         if(d>>i&1)x=fa[x][i];
 31     for(int i=21;x!=y;i?i--:i)
 32         if(fa[x][i]!=fa[y][i]||!i)
 33             x=fa[x][i],y=fa[y][i];
 34     return x;    
 35 }
 36 
 37 int Add(int x,int d){
 38     while(x<N){
 39         bit[x]+=d;
 40         x+=x&(-x);
 41     }
 42 }
 43 
 44 int Query(int x){
 45     int ret=0;
 46     while(x){
 47         ret+=bit[x];
 48         x-=x&(-x);
 49     }
 50     return ret;
 51 }
 52 
 53 bool cmp(int x,int y){return id[x]<id[y];}
 54 
 55 int main(){
 56     freopen("divljak.in","r",stdin);
 57     freopen("divljak.out","w",stdout);
 58     ios::sync_with_stdio(false);
 59     cin.tie(NULL),cout.tie(NULL);
 60     cin>>n;
 61     for(int t=1;t<=n;t++){
 62         cin>>s;
 63         len=strlen(s);int p=0;
 64         for(int i=0;i<len;i++)
 65             if(ch[p][s[i]-'a'])
 66                 p=ch[p][s[i]-'a'];
 67             else
 68                 p=ch[p][s[i]-'a']=++cnt;
 69         pd[t]=p;            
 70     }
 71     for(int i=0;i<26;i++)
 72         if(ch[0][i])q.push(ch[0][i]);
 73     
 74     while(!q.empty()){
 75         int x=q.front();q.pop();
 76         for(int i=0;i<26;i++)
 77             if(ch[x][i])fail[ch[x][i]]=ch[fail[x]][i],q.push(ch[x][i]);
 78             else ch[x][i]=ch[fail[x]][i];
 79     }
 80     for(int i=1;i<=cnt;i++)
 81         addedge(fail[i],i);
 82     DFS(0,0);
 83     for(int k=1;k<=21;k++)
 84         for(int i=1;i<=cnt;i++)
 85             fa[i][k]=fa[fa[i][k-1]][k-1];        
 86     cin>>Q;
 87     while(Q--){
 88         cin>>tp;
 89         if(tp==1){
 90             cin>>s;top=0;
 91             len=strlen(s);int p=0;
 92             for(int i=0;i<len;i++){
 93                 while(p&&!ch[p][s[i]-'a'])p=fail[p];
 94                 p=ch[p][s[i]-'a'];if(p!=0)st[++top]=p;
 95             }
 96             sort(st+1,st+top+1,cmp);p=0;
 97             for(int i=1;i<=top;i++)
 98                 if(st[i]!=st[i-1])
 99                     st[++p]=st[i];
100             top=p;
101             for(int i=1;i<=top;i++)
102                 Add(id[st[i]],1);    
103             for(int i=2;i<=top;i++)
104                 Add(id[Lca(st[i],st[i-1])],-1);    
105         }
106         else{
107             cin>>x;
108             cout<<Query(ed[pd[x]])-Query(id[pd[x]]-1)<<"\n";
109         }
110     }
111     //cout<<1.0*clock()/CLOCKS_PER_SEC<<"\n";
112     return 0;
113 }

  只快了那么一点点 = =

 

posted @ 2016-09-13 21:43  TenderRun  阅读(235)  评论(0编辑  收藏  举报