HDOJ4601 Letter Tree
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDOJ4601 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()
以上是关于HDOJ4601 Letter Tree的主要内容,如果未能解决你的问题,请参考以下文章
HDOJ 4582 - DFS spanning tree - DFS树,贪心
codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths