AC自动机+树链剖分HDU 5566

Posted uuuxxllj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC自动机+树链剖分HDU 5566相关的知识,希望对你有一定的参考价值。

离线做法

对给出的树作树剖

把每个询问区间先加入线段树的结点

后对线段树每个有询问的节点建立AC自动机

对每个节点单独询问

技术图片
  1 // #include <bits/stdc++.h>
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <cstring>
  6 #include <cctype>
  7 #include <algorithm>
  8 #define For(i,a,b) for(int i=a;i<=b;++i)
  9 #define Dec(i,b,a) for(int i=b;i>=a;--i)
 10 #define file() freopen("c://users/asus/desktop/v.txt","r",stdin);
 11 #define inf 0x3f3f3f3f
 12 using namespace std;
 13 
 14 typedef long long ll;
 15 inline ll qr(){
 16     ll x=0,f=1; char ch;
 17     while(!isdigit(ch=getchar())) if(ch==-) f=-1;
 18     for(;isdigit(ch);x=x*10+ch-48,ch=getchar());
 19     return x*f;
 20 }
 21 // #define cmax(x,y) (x<y?x=y:0)
 22 #define mid (l+r>>1)
 23 #define lc x<<1
 24 #define rc x<<1|1
 25 const int N = 100010;
 26 void cmax(int &x,int y){if(x<y) x=y;}
 27 struct ACA {
 28     int c[N][26],f[N],w[N],len[N],ct;
 29     void clr(int x) {
 30         memset(c[x],0,sizeof c[x]);
 31         w[x]=len[x]=f[x]=0;
 32     }
 33     void init() {clr(ct=0); }
 34     void ins(string s)
 35     {
 36         int u=0;
 37         for(int i=0;i<s.length();++i)
 38         {
 39             int v=s[i]-a;
 40             if(!c[u][v]) c[u][v]=++ct,clr(ct);
 41             u=c[u][v];
 42         }
 43         w[u]=1;
 44         len[u]=s.length();
 45     }
 46     void getfail()
 47     {
 48         queue<int> q;
 49         For(i,0,25) if(c[0][i]) q.push(c[0][i]);
 50         while(!q.empty())
 51         {
 52             int u=q.front(); q.pop();
 53             For(i,0,25)
 54             {
 55                 int &v=c[u][i];
 56                 if(v) f[v]=c[f[u]][i],q.push(v),cmax(len[v],len[f[v]]);
 57                 else v=c[f[u]][i];
 58             }
 59         }
 60     }
 61     int qry(string s)
 62     {
 63         int res=0,u=0;
 64         for(int i=0;i<s.length();++i)
 65         {
 66             u=c[u][s[i]-a];
 67             cmax(res,len[u]);
 68         }
 69         return res;
 70     }
 71 } aca;
 72 
 73 string s[N],t[N];
 74 int ans[N],n,m,idx;
 75 vector<int> a[N<<2],g[N];
 76 int sz[N],d[N],fa[N],son[N],b[N],id[N],top[N];
 77 
 78 void build(int x,int l,int r)
 79 {
 80     a[x].clear();
 81     if(l==r) return;
 82     build(lc,l,mid); build(rc,mid+1,r);
 83 }
 84 void qry(int x,int l,int r,int L,int R,int k)
 85 {
 86     if(L<=l&&r<=R) return(void)(a[x].push_back(k));
 87     if(L<=mid) qry(lc,l,mid,L,R,k);
 88     if(R>mid) qry(rc,mid+1,r,L,R,k);
 89 }
 90 void getans(int x,int l,int r)
 91 {
 92     if(a[x].size())
 93     {
 94         aca.init();
 95         For(i,l,r) aca.ins(s[b[i]]);
 96         aca.getfail();
 97         for(int i=0;i<a[x].size();++i)
 98             cmax(ans[a[x][i]],aca.qry(t[a[x][i]]));
 99     }
100     if(l==r) return;
101     getans(lc,l,mid); getans(rc,mid+1,r);
102 }
103 void init()
104 {
105     idx=0;
106     fill(son,son+1+n,0);
107     For(i,1,n) g[i].clear();
108 }
109 
110 void dfs1(int u,int ff)
111 {
112     sz[u]=1; d[u]=d[ff]+1; fa[u]=ff;
113     for(int i=0,v;i<g[u].size();++i)
114     {
115         if((v=g[u][i])==ff) continue;
116         dfs1(v,u); sz[u]+=sz[v];
117         if(sz[v]>sz[son[u]]) son[u]=v;
118     }
119 }
120 void dfs2(int u,int tp)
121 {
122     id[u]=++idx; b[idx]=u; top[u]=tp;
123     if(!son[u]) return;
124     dfs2(son[u],tp);
125     for(int i=0,v;i<g[u].size();++i)
126         if((v=g[u][i])!=fa[u] && v!=son[u]) dfs2(v,v);
127 }
128 void qrypath(int x,int y,int k)
129 {
130     while(top[x]!=top[y])
131     {
132         if(d[top[x]]<d[top[y]]) swap(x,y);
133         qry(1,1,n,id[top[x]],id[x],k);
134         x=fa[top[x]];
135     }
136     if(d[x]>d[y]) swap(x,y);
137     qry(1,1,n,id[x],id[y],k);
138 }
139 int main()
140 {
141     // file();
142     ios::sync_with_stdio(0);
143     int kase;
144     cin >> kase;
145      while(kase--)
146     {
147         cin >> n; int x,y;
148         build(1,1,n);        
149         init();
150         For(i,1,n) cin >> s[i];
151         For(i,2,n)
152         {
153             cin >> x;
154             g[x].push_back(i);
155             g[i].push_back(x);
156         }
157         dfs1(1,0); dfs2(1,1);
158         cin >> m;
159         For(i,1,m)
160         {
161             cin >> x >> y >> t[i];
162             qrypath(x,y,i);
163         }
164         memset(ans,0,sizeof ans);
165         getans(1,1,n);
166         For(i,1,m) cout << ans[i] << endl;
167     }
168     return 0;
169 }
View Code

 

以上是关于AC自动机+树链剖分HDU 5566的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5044 Tree(树链剖分)

hdu 5044 Tree (树链剖分+标记数组)

hdu 2586 How far away?(树链剖分+前缀和)

[HDU5029]Relief grain(树链剖分+线段树)

HDU 3966 Aragorn&#39;s Story(树链剖分)

hdu6547Tree(树链剖分, 线段树区间根号)