【HDOJ】4366 Successor
基本思路是将树形结构转换为线性结构。然后,所求即为一个区间内大于abi的最大的loy指向的ID。
将结点按照abi降序排序,注意abi可能相等。
然后,使用线段树单点更新,区间查询可解。
1 /* 4366 */ 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 43 typedef struct node_t { 44 int abi, id; 45 46 friend bool operator< (const node_t& a, const node_t& b) { 47 return a.abi > b.abi; 48 } 49 50 } node_t; 51 52 typedef struct { 53 int v, nxt; 54 } edge_t; 55 56 const int maxv = 50005; 57 const int maxn = 50005; 58 int abi[maxv], loy[maxv]; 59 int head[maxv]; 60 edge_t E[maxv]; 61 int mx[maxn<<2]; 62 int ID[maxn<<2]; 63 int Beg[maxv], End[maxv], dfs_clock; 64 node_t nd[maxn]; 65 int ans[maxn]; 66 int n, m, l; 67 68 void init() { 69 memset(head, -1, sizeof(head)); 70 l = dfs_clock = 0; 71 } 72 73 void addEdge(int u, int v) { 74 E[l].v = v; 75 E[l].nxt = head[u]; 76 head[u] = l++; 77 } 78 79 inline void PushUp(int rt) { 80 int lb = rt<<1; 81 int rb = lb|1; 82 83 if (mx[lb] > mx[rb]) { 84 mx[rt] = mx[lb]; 85 ID[rt] = ID[lb]; 86 } else { 87 mx[rt] = mx[rb]; 88 ID[rt] = ID[rb]; 89 } 90 } 91 92 void Build(int l, int r, int rt) { 93 mx[rt] = -1; 94 if (l == r) 95 return ; 96 97 int mid = (l + r) >> 1; 98 Build(lson); 99 Build(rson); 100 101 PushUp(rt); 102 } 103 104 void Update(int x, int id, int val, int l, int r, int rt) { 105 if (l == r) { 106 mx[rt] = val; 107 ID[rt] = id; 108 return ; 109 } 110 111 int mid = (l + r) >> 1; 112 113 if (x <= mid) 114 Update(x, id, val, lson); 115 else 116 Update(x, id, val, rson); 117 118 PushUp(rt); 119 } 120 121 pii Query(int L, int R, int l, int r, int rt) { 122 if (L==l && R==r) { 123 return mp(mx[rt], ID[rt]); 124 } 125 126 int mid = (l + r) >> 1; 127 128 if (R <= mid) { 129 return Query(L, R, lson); 130 } else if (L > mid) { 131 return Query(L, R, rson); 132 } else { 133 pii ltmp = Query(L, mid, lson); 134 pii rtmp = Query(mid+1, R, rson); 135 if (ltmp.fir > rtmp.fir) 136 return ltmp; 137 else 138 return rtmp; 139 } 140 } 141 142 void dfs(int u) { 143 int v, k; 144 145 Beg[u] = ++dfs_clock; 146 for (k=head[u]; k!=-1; k=E[k].nxt) { 147 v = E[k].v; 148 dfs(v); 149 } 150 End[u] = dfs_clock; 151 } 152 153 void solve() { 154 155 dfs(0); 156 int nn = dfs_clock; 157 memset(mx, -1, sizeof(mx)); 158 159 rep(i, 1, n) { 160 nd[i-1].abi = abi[i]; 161 nd[i-1].id = i; 162 } 163 164 int mm = n - 1; 165 sort(nd, nd+mm); 166 167 int u; 168 pii p; 169 int i = 0; 170 171 while (i < mm) { 172 int j = i; 173 while (i<mm && nd[i].abi==nd[j].abi) { 174 u = nd[i].id; 175 int l = Beg[u]+1; 176 int r = End[u]; 177 if (l > r) { 178 ans[u] = -1; 179 } else { 180 p = Query(l, r, 1, nn, 1); 181 ans[u] = p.fir==-1 ? -1:p.sec; 182 } 183 ++i; 184 } 185 186 while (j < i) { 187 u = nd[j].id; 188 Update(Beg[u], u, loy[u], 1, nn, 1); 189 ++j; 190 } 191 } 192 193 194 while (m--) { 195 scanf("%d", &u); 196 printf("%d\n", ans[u]); 197 } 198 } 199 200 int main() { 201 ios::sync_with_stdio(false); 202 #ifndef ONLINE_JUDGE 203 freopen("data.in", "r", stdin); 204 freopen("data.out", "w", stdout); 205 #endif 206 207 int t; 208 int u; 209 210 scanf("%d", &t); 211 while (t--) { 212 init(); 213 scanf("%d %d", &n, &m); 214 rep(i, 1, n) { 215 scanf("%d %d %d", &u, &loy[i], &abi[i]); 216 addEdge(u, i); 217 } 218 solve(); 219 } 220 221 #ifndef ONLINE_JUDGE 222 printf("time = %d.\n", (int)clock()); 223 #endif 224 225 return 0; 226 }
数据发生器。
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 10 10 fout.write("%d\n" % (t)) 11 for tt in xrange(t): 12 n = randint(200, 300) 13 m = randint(200, 300) 14 fout.write("%d %d\n" % (n, m)) 15 ust = [0] 16 st = set() 17 for i in xrange(1, n): 18 idx = randint(0, len(ust)-1) 19 a = ust[idx] 20 b = randint(0, 105) 21 while True: 22 c = randint(0, 10**6) 23 if c not in st: 24 break 25 st.add(c) 26 fout.write("%d %d %d\n" % (a, c, b)) 27 ust.append(i) 28 L = [] 29 for i in xrange(m): 30 x = randint(1, n-1) 31 L.append(x) 32 fout.write("\n".join(map(str, L)) + "\n") 33 34 def MovDataIn(): 35 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 36 shutil.copyfile("data.in", desFileName) 37 38 39 if __name__ == "__main__": 40 GenDataIn() 41 MovDataIn()