HDU5069(AC自动机+线段树)

题意:http://acm.hdu.edu.cn/showproblem.php?pid=5069

给你n个串,m个询问:以b串的前缀和a串的后缀最长是多少。

思路:https://blog.csdn.net/gatevin/article/details/46123703

讲的很全面了。

  1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0);
  2 #include <cstdio>//sprintf islower isupper
  3 #include <cstdlib>//malloc  exit strcat itoa system("cls")
  4 #include <iostream>//pair
  5 #include <fstream>//freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin);
  6 #include <bitset>
  7 //#include <map>
  8 //#include<unordered_map>
  9 #include <vector>
 10 #include <stack>
 11 #include <set>
 12 #include <string.h>//strstr substr strcat
 13 #include <string>
 14 #include <time.h>// srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
 15 #include <cmath>
 16 #include <deque>
 17 #include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
 18 #include <vector>//emplace_back
 19 //#include <math.h>
 20 #include <cassert>
 21 #include <iomanip>
 22 //#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
 23 #include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
 24 using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
 25 //******************
 26 clock_t __START,__END;
 27 double __TOTALTIME;
 28 void _MS(){__START=clock();}
 29 void _ME(){__END=clock();__TOTALTIME=(double)(__END-__START)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
 30 //***********************
 31 #define rint register int
 32 #define fo(a,b,c) for(rint a=b;a<=c;++a)
 33 #define fr(a,b,c) for(rint a=b;a>=c;--a)
 34 #define mem(a,b) memset(a,b,sizeof(a))
 35 #define pr printf
 36 #define sc scanf
 37 #define ls rt<<1
 38 #define rs rt<<1|1
 39 typedef pair<int,int> PII;
 40 typedef vector<int> VI;
 41 typedef unsigned long long ull;
 42 typedef long long ll;
 43 typedef double db;
 44 const db E=2.718281828;
 45 const db PI=acos(-1.0);
 46 const ll INF=(1LL<<60);
 47 const int inf=(1<<30);
 48 const db ESP=1e-9;
 49 const int mod=(int)1e9+7;
 50 const int N=(int)2e5+10;
 51 
 52 char s[N];
 53 int in_id[N];
 54 struct node
 55 {
 56     int l,r;
 57 }P[N];
 58 
 59 ll max_[N<<2],add[N<<2];
 60 
 61 void up(int rt,int l,int r){
 62     max_[rt]=max(max_[ls],max_[rs]);
 63 }
 64 void dn(int rt){
 65     if(add[rt]!=0)
 66     {
 67         max_[ls]=max(max_[ls],add[rt]);
 68         max_[rs]=max(max_[rs],add[rt]);
 69         add[ls]=max(add[ls],add[rt]);
 70         add[rs]=max(add[rs],add[rt]);
 71         add[rt]=0;
 72     }
 73 }
 74 void Build(int l,int r,int rt)
 75 {
 76     max_[rt]=0;
 77     add[rt]=0;
 78     if(l==r)
 79     {
 80         return;
 81     }
 82     int mid=(l+r)>>1;
 83 
 84     Build(l,mid,rt<<1);
 85     Build(mid+1,r,rt<<1|1);
 86     up(rt,l,r);
 87 }
 88 ll query_dot(int pos,int l,int r,int rt)
 89 {
 90     if(l==r)
 91     {
 92         return max_[rt];
 93     }
 94 
 95     int mid=(l+r)>>1;
 96     dn(rt);
 97     if(pos<=mid)
 98         return query_dot(pos,l,mid,rt<<1);
 99     else
100         return query_dot(pos,mid+1,r,rt<<1|1);
101 }
102 void update_qu(int L,int R,ll V,int l,int r,int rt)
103 {
104     if(L>R)return;
105     if(L<=l&&r<=R)
106     {
107         max_[rt]=max(max_[rt],V);
108         add[rt]=max(add[rt],V);
109         return;
110     }
111 
112     int mid=(l+r)>>1;
113     dn(rt);
114     if(L<=mid)
115         update_qu(L,R,V,l,mid,rt<<1);
116     if(R>mid)
117         update_qu(L,R,V,mid+1,r,rt<<1|1);
118     up(rt,l,r);
119 }
120 //-----------------------线段树
121 //====================================================================
122 class MAP
123 {
124 public:
125     struct EDGE
126     {
127         int to,next;
128     }edge[N];
129 
130     int tot;
131     int head[N];
132 
133     int dfn[N],DFN,SZ[N];
134     void Init(int n)
135     {
136         tot=DFN=0;
137         for(int i=0;i<=n;++i)
138             head[i]=SZ[i]=dfn[i]=0;
139     }
140     void add(int from,int to)
141     {
142         ++tot;
143         edge[tot].to=to;
144         edge[tot].next=head[from];
145         head[from]=tot;
146     }
147     int dfs(int u,int fa)
148     {
149         dfn[u]=++DFN;
150         SZ[dfn[u]]=1;
151         for(int i=head[u];i;i=edge[i].next)
152         {
153             int to=edge[i].to;
154             if(to!=fa)
155                 SZ[dfn[u]]+=dfs(to,u);
156         }
157         return SZ[dfn[u]];
158     }
159 }mp;
160 //====================================================================
161 //------------------------AC
162 class ac_automaton//失配时,尽可能长得保留后缀以重新开始匹配.
163 {
164 public:
165     int tot;
166     int trie[N][27];
167     int fail[N];
168     //other
169     //--------------
170     void Init(int n)
171     {
172         tot=0;
173         for(int i=0;i<=n;++i)
174         {
175             fail[i]=0;
176             for(int j=1;j<=26;++j)
177                 trie[i][j]=0;
178         }
179     }
180     int Insert(int l,int r)
181     {
182         int rt=0;
183         for(int i=l;i<=r;++i)
184         {
185             int id=s[i]-'A'+1;
186             if(!trie[rt][id])trie[rt][id]=++tot;
187             rt=trie[rt][id];
188         }
189         return rt;
190     }
191     void Getfail()
192     {
193         queue<int>q;
194         for(int i=1;i<=26;++i)
195         {
196             int id=trie[0][i];
197             if(id)
198             {
199                 fail[id]=0;
200                 q.push(id);
201             }
202         }
203         while(!q.empty())
204         {
205             int rt=q.front();q.pop();
206             for(int i=1;i<=26;++i)
207             {
208                 int id=trie[rt][i];
209                 if(id)
210                 {
211                     fail[id]=trie[fail[rt]][i];
212                     q.push(id);
213                 }
214                 else
215                     trie[rt][i]=trie[fail[rt]][i];
216             }
217         }
218     }
219     void Find(int l,int r,ll sgm)
220     {
221         int rt=0;
222         for(int i=l;i<=r;++i)
223         {
224             rt=trie[rt][s[i]-'A'+1];
225             int pos=mp.dfn[rt];
226             update_qu(pos,pos+mp.SZ[pos]-1,i-l+1+sgm,1,tot+1,1);
227         //    for(int j=1;j<=tot+1;++j)check(j,1,tot+1,1);
228         //    cout<<endl;
229         }
230     }
231 }AC;
232 
233 struct GG
234 {
235     int id,to_a;
236 };
237 vector<vector<GG> >G(N);
238 ll ans[N];
239 int aa[N],bb[N];
240 
241 int main()
242 {
243 //    freopen("C:\\Users\\13606\\Desktop\\Input.txt","r",stdin);
244 //    freopen("C:\\Users\\13606\\Desktop\\1.txt","w",stdout);
245     int n,m;
246     while(~sc("%d%d",&n,&m))
247     {
248         for(int i=1;i<=n;++i)G[i].clear();
249         int len=0;
250         for(int i=1;i<=n;++i)
251         {
252             sc("%s",s+1+len);
253             P[i].l=1+len;
254             len+=strlen(s+1+len);
255             P[i].r=len;
256         }
257         AC.Init(len);
258         for(int i=1;i<=n;++i)
259             in_id[i]=AC.Insert(P[i].l,P[i].r);
260         AC.Getfail();
261         int tot=AC.tot+1;
262         Build(1,tot,1);
263 
264         for(int i=1;i<=m;++i)
265         {
266             int a,b;
267             sc("%d%d",&a,&b);
268             aa[i]=a,bb[i]=b;
269             G[b].push_back({i,a});
270         }
271         mp.Init(tot);
272         for(int i=1;i<=AC.tot;i++)
273         {
274             mp.add(i,AC.fail[i]);
275             mp.add(AC.fail[i],i);
276         }
277         mp.dfs(0,-1);
278         ll sgm=-100000000;
279         for(int i=1;i<=n;++i)
280         {
281             sgm+=100000000;
282             AC.Find(P[i].l,P[i].r,sgm);
283             int sz=G[i].size();
284             for(int j=0;j<sz;++j)
285             {
286                 GG now=G[i][j];
287                 ans[now.id]=max(0LL,query_dot(mp.dfn[in_id[now.to_a]],1,tot,1)-sgm);
288             }
289         }
290         for(int i=1;i<=m;++i)
291             pr("%lld\n",ans[i]);
292     }
293     return 0;
294 }
295 
296 /**************************************************************************************/

 

posted @ 2020-02-05 14:47  ZMWLxh  阅读(273)  评论(0编辑  收藏  举报