【HDOJ】4601 Letter Tree

挺有意思的一道题,思路肯定是将图转化为Trie树,这样可以求得字典序。
然后,按照trie的层次求解。一直wa的原因在于将树转化为线性数据结构时要从原树遍历,从trie遍历就会wa。不同结点可能映射为trie上的同一结点,如
1->2 (a) 1->3(a) 2->4(b), 这是trie的结构是RT->a->b。然而,从结点3不能找到权重为b的路径。
用RMQ求满足边界的rank最大值,通过sa找到该最大值对应的trie上的根。从而求解。

  1 /* 4601 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <cmath>
 14 #include <ctime>
 15 #include <cstring>
 16 #include <climits>
 17 #include <cctype>
 18 #include <cassert>
 19 #include <functional>
 20 #include <iterator>
 21 #include <iomanip>
 22 using namespace std;
 23 //#pragma comment(linker,"/STACK:102400000,1024000")
 24 
 25 #define sti                set<int>
 26 #define stpii            set<pair<int, int> >
 27 #define mpii            map<int,int>
 28 #define vi                vector<int>
 29 #define pii                pair<int,int>
 30 #define vpii            vector<pair<int,int> >
 31 #define rep(i, a, n)     for (int i=a;i<n;++i)
 32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 33 #define clr                clear
 34 #define pb                 push_back
 35 #define mp                 make_pair
 36 #define fir                first
 37 #define sec                second
 38 #define all(x)             (x).begin(),(x).end()
 39 #define SZ(x)             ((int)(x).size())
 40 #define lson            l, mid, rt<<1
 41 #define rson            mid+1, r, rt<<1|1
 42 // #define DEBUG 
 43 
 44 typedef struct {
 45     int u, v, w;
 46     int nxt;
 47 } edge_t;
 48 
 49 typedef struct ques_t {
 50     int u, m, id;
 51 
 52     ques_t() {}
 53     friend bool operator< (const ques_t& a, const ques_t& b) {
 54         if (a.m == b.m)
 55             return a.id < b.id;
 56         return a.m < b.m;
 57     }
 58 
 59 } ques_t;
 60 
 61 const int mod = 1e9+7;
 62 const int maxn = 1e5+5;
 63 const int maxv = maxn;
 64 const int maxe = maxv * 2;
 65 int head[maxv], m;
 66 edge_t E[maxe];
 67 int nxt[maxn][26], l;
 68 int Pos[maxv], Rank[maxv], sa[maxv];
 69 __int64 Base[maxn];
 70 __int64 Val[maxn];
 71 int deep[maxv];
 72 int fr[maxv], to[maxv];
 73 int dfs_clock;
 74 vi layer[maxn];
 75 int maxd;
 76 int n, qn, q;
 77 ques_t Qu[maxn];
 78 int ans[maxn];
 79 int dp[17][maxn];
 80 int D[maxn];
 81 
 82 void Init() {
 83     Base[0] = 1;
 84     rep(i, 1, maxn)
 85         Base[i] = Base[i-1] * 26 % mod;
 86 }
 87 
 88 void init() {
 89     memset(head, -1, sizeof(head));
 90     m = 0;
 91     memset(nxt[1], 0, sizeof(nxt[1]));
 92     l = 1;
 93     dfs_clock = 0;
 94     maxd = 0;
 95     rep(i, 0, n+1)
 96         layer[i].clr();
 97 }
 98 
 99 int newNode() {
100     ++l;
101     memset(nxt[l], 0, sizeof(nxt[l]));
102     Val[l] = 0;
103     return l;
104 }
105 
106 void addEdge(int u, int v, int w) {
107     E[m].v = v;
108     E[m].w = w;
109     E[m].nxt = head[u];
110     head[u] = m++;
111 
112     E[m].v = u;
113     E[m].w = w;
114     E[m].nxt = head[v];
115     head[v] = m++;
116 }
117 
118 void Build_Trie(int u, int fa, int rt) {
119     int v, k, p;
120 
121     Pos[u] = rt;
122     for (k=head[u]; k!=-1; k=E[k].nxt) {
123         v = E[k].v;
124         if (v == fa)
125             continue;
126 
127         int id = E[k].w;
128         p = nxt[rt][id];
129         if (!p)
130             p = nxt[rt][id] = newNode();
131         Build_Trie(v, u, p);
132     }
133 }
134 
135 void Mark_Rank(int rt, int d) {
136     int p;
137 
138     Rank[rt] = ++dfs_clock;
139     sa[dfs_clock] = rt;
140     rep(i, 0, 26) {
141         p = nxt[rt][i];
142         if (p) {
143             Val[p] = (Val[rt]*26 + i) % mod;
144             Mark_Rank(p, d+1);
145         }
146     }
147 }
148 
149 void calDepth(int u, int fa, int rt) {
150     int v, k, p;
151     
152     D[++dfs_clock] = Rank[rt];
153     fr[u] = dfs_clock + 1;
154     maxd = max(deep[u], maxd);
155     layer[deep[u]].pb(dfs_clock);
156     for (k=head[u]; k!=-1; k=E[k].nxt) {
157         v = E[k].v;
158         if (v == fa)
159             continue;
160         deep[v] = deep[u] + 1;
161         p = nxt[rt][E[k].w];
162         calDepth(v, u, p);
163     }
164     to[u] = dfs_clock;
165 }
166 
167 void init_RMQ(int d, int n) {
168     int i, j;
169 
170     for (i=0; i<n; ++i)
171         dp[0][i] = D[layer[d][i]];
172     for (j=1; (1<<j)<=n; ++j)
173         for (i=0; i+(1<<j)-1<n; ++i)
174             dp[j][i] = max(dp[j-1][i], dp[j-1][i+(1<<(j-1))]);
175 }
176 
177 int RMQ(int l, int r) {
178     if (l > r)
179         swap(l, r);
180 
181     int k = 0;
182 
183     while ((1<<(k+1)) <= r-l+1)
184         ++k;
185 
186     return max(dp[k][l], dp[k][r-(1<<k)+1]);
187 }
188 
189 int calc(int qid, int d) {
190     int u = Qu[qid].u;
191     int rt = Pos[u];
192     int b = fr[u];
193     int e = to[u];
194     int l = lower_bound(all(layer[d]), b) - layer[d].begin();
195     int r = upper_bound(all(layer[d]), e) - layer[d].begin();
196     --r;
197     
198     if (l > r)
199         return -1;
200 
201     int mxrank = RMQ(l, r);
202     int mxrt = sa[mxrank];
203     int delta = d - deep[u];
204     int ret = (Val[mxrt] - Val[rt] * Base[delta] % mod + mod) % mod;
205 
206     return ret;
207 }
208 
209 void solve() {
210     Build_Trie(1, 0, 1);
211     Mark_Rank(1, 0);
212     dfs_clock = 0;
213     deep[1] = 0;
214     calDepth(1, 0, 1);
215     
216     scanf("%d", &q);
217     qn = 0;
218     rep(i, 0, q) {
219         scanf("%d %d", &Qu[qn].u, &Qu[qn].m);
220         int deepu = deep[Qu[qn].u];
221         if (Qu[qn].m == 0) {
222             ans[i] = 0;
223         } else if (deepu+Qu[qn].m > maxd) {
224             ans[i] = -1;
225         } else {
226             Qu[qn].m += deepu;
227             Qu[qn].id = i;
228             ++qn;
229         }
230     }
231     
232     if (qn) {
233         sort(Qu, Qu+qn);
234         int j = 0;
235         rep(i, 0, maxd+1) {
236             if (i < Qu[j].m)
237                 continue;    
238             int sz = SZ(layer[i]);
239             init_RMQ(i, sz);
240             while (j<=qn && Qu[j].m==i) {
241                 int id = Qu[j].id;
242                 ans[id] = calc(j, i);
243                 ++j;
244             }
245             if (j == qn)
246                 break;
247         }
248     }
249 
250     rep(i, 0, q) {
251         if (ans[i] == -1)
252             puts("IMPOSSIBLE");
253         else
254             printf("%d\n", ans[i]);
255     }
256 }
257 
258 int main() {
259     ios::sync_with_stdio(false);
260     #ifndef ONLINE_JUDGE
261         freopen("data.in", "r", stdin);
262         freopen("data.out", "w", stdout);
263     #endif
264 
265     int t;
266     int u, v;
267     char ws[4];
268 
269     Init();
270     scanf("%d", &t);
271     while (t--) {
272         scanf("%d", &n);
273         init();
274         rep(i, 1, n) {
275             scanf("%d %d %s", &u, &v, ws);
276             addEdge(u, v, ws[0]-'a');
277         }
278         solve();
279     }
280 
281     #ifndef ONLINE_JUDGE
282         printf("time = %d.\n", (int)clock());
283     #endif
284 
285     return 0;
286 }

 数据发生器。

 1 from random import randint, shuffle
 2 import shutil
 3 import string
 4 
 5 
 6 def GenDataIn():
 7     with open("data.in", "w") as fout:
 8         t = 10
 9         bound = 10**3
10         lc = list(string.lowercase)
11         fout.write("%d\n" % (t))
12         for tt in xrange(t):
13             n = randint(300, 500)
14             fout.write("%d\n" % (n))
15             ust = [1]
16             vst = range(2, n+1)
17             for i in xrange(1, n):
18                 uid = randint(0, len(ust)-1)
19                 vid = randint(0, len(vst)-1)
20                 u = ust[uid]
21                 v = vst[vid]
22                 ust.append(v)
23                 vst.remove(v)
24                 idx = randint(0, 25)
25                 c = lc[idx]
26                 fout.write("%d %d %s\n" % (u, v, c))
27             q = randint(400, 600)
28             fout.write("%d\n" % (q))
29             for i in xrange(q):
30                 u = randint(1, n+1)
31                 m = randint(0, 10)
32                 fout.write("%d %d\n" % (u, m))
33                 
34                 
35 def MovDataIn():
36     desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
37     shutil.copyfile("data.in", desFileName)
38 
39     
40 if __name__ == "__main__":
41     GenDataIn()
42     MovDataIn()

 

posted on 2016-02-06 15:56  Bombe  阅读(168)  评论(0编辑  收藏  举报

导航