# bzoj 2434 [NOI2011] 阿狸的打字机

https://www.lydsy.com/JudgeOnline/problem.php?id=2434

Code：

  1 #include<stdio.h>
2 #include<cstring>
3 #include<cstdlib>
4 #include<algorithm>
5 #include<vector>
6 #include<map>
7 #include<set>
8 #include<cmath>
9 #include<iostream>
10 #include<queue>
11 #include<string>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pii;
15 typedef long double ld;
16 typedef unsigned long long ull;
17 typedef pair<long long,long long> pll;
18 #define fi first
19 #define se second
20 #define pb push_back
21 #define mp make_pair
22 #define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
23 #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
24
26     ll x=0,f=1;char c=getchar();
27     while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
28     while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
29     return x*f;
30 }
31
32 const int maxnode=150100;
33 const int maxn=100100;
34
35 #define lowbit(x) (x&-x)
36 struct BIT{
37     int a[maxn*5];
39         while(x<=maxn*4){
40             a[x]+=val;
41             x+=lowbit(x);
42         }
43     }
45         int ret=0;
46         while(x){ret+=a[x];x-=lowbit(x);}
47         return ret;
48     }
49 } bit;
50
51 vector<pii> q[maxn];
52 string s;
53 int l[maxn],r[maxn],tim;
54 int ans[maxn];
55 int dy[maxn*4];
57 int nums;
58
61 }
62
63 struct Trie{
64     int nxt[maxnode][26],fail[maxnode],en[maxnode];
65     int root,sz;
66     int fa[maxnode];
67     int nxt2[maxnode][26];
68
69     int newnode(){
70         for(int i=0;i<26;i++) nxt[sz][i]=-1;
71         en[sz]=0;sz++;
72         return sz-1;
73     }
74     void init(){
75         sz=0;
76         root=newnode();
77     }
78
79     void doit(){
80         getline(cin,s);
81         int nw=root;
82         for(int i=0;i<s.size();i++){
83             if(s[i]=='P') en[nw]=++nums,dy[nums]=nw;
84             else if(s[i]=='B') nw=fa[nw];
85             else{
86                 if(nxt[nw][s[i]-'a']==-1) nxt[nw][s[i]-'a']=newnode();
87                 fa[nxt[nw][s[i]-'a']]=nw;
88                 nw=nxt[nw][s[i]-'a'];
89             }
90         }
91     }
92     void build(){
93         for(int i=0;i<sz;i++)
94             for(int j=0;j<26;j++)
95                 nxt2[i][j]=nxt[i][j];
96         queue<int> q;
97         fail[root]=root;
98         for(int i=0;i<26;i++)
99             if(nxt[root][i]==-1) nxt[root][i]=root;
100             else{
101                 fail[nxt[root][i]]=root;
102                 q.push(nxt[root][i]);
103             }
104         while(!q.empty()){
105             int nw=q.front();q.pop();
106             for(int i=0;i<26;i++)
107                 if(nxt[nw][i]==-1) nxt[nw][i]=nxt[fail[nw]][i];
108                 else{
109                     if(nxt[nw][i]==0){
110                         cout<<nw<<endl;
111                         break;
112                     }
113                     fail[nxt[nw][i]]=nxt[fail[nw]][i];
114                     q.push(nxt[nw][i]);
115                 }
116         }
117         for(int i=1;i<sz;i++){
118             int u=i,v=fail[u];
120         }
121     }
122
123     void dfs(int u){
125         if(en[u]){
126             for(int i=0;i<q[en[u]].size();i++){
127                 int v=q[en[u]][i].fi;v=dy[v];
128                 int ind=q[en[u]][i].se;
130             }
131         }
132         for(int i=0;i<26;i++)
133             if(nxt2[u][i]!=-1) dfs(nxt2[u][i]);
135     }
136 } tr;
137
138 inline void dfs(int u){
139     l[u]=++tim;
140     r[u]=l[u];
142         int v=to[i];
143         dfs(v);
144         r[u]=r[v];
145     }
146 }
147
148 int main(){
149 //    freopen("2434.in","r",stdin);
150 //    freopen("2434.out","w",stdout);
151     tr.init();
152     tr.doit();
153     tr.build();
155     for(int i=1;i<=m;i++){
157         q[y].pb(mp(x,i));
158     }
159     dfs(0);
160     tr.dfs(0);
161     for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
162     return 0;
163 }
164
165 /*
166 aPaPBbP
167 3
168 1 2
169 1 3
170 2 3
171 */
View Code

Review：

1. 卡了几个月的问题：输入超时

我们不能维护一个字符串表示当前打字机内的字符串，然后每次暴力插入，这样就超时了

我们应该维护一个当前在trie上的节点，然后来回移动

2. 怎么想：

其实不难想

首先肯定上AC自动机，然后询问肯定得离线，那么就是求子树内的和，用dfs序转化成序列上的和是常规套路了

posted @ 2018-08-26 22:46  wawawa8  阅读(115)  评论(0编辑  收藏  举报