[SPOJ]Query on a tree(树链剖分,线段树)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SPOJ]Query on a tree(树链剖分,线段树)相关的知识,希望对你有一定的参考价值。
题目链接:http://www.spoj.com/problems/QTREE/en/
照着集训队论文敲的…万幸树剖部分没写错…
1 #include <algorithm> 2 #include <iostream> 3 #include <iomanip> 4 #include <cstring> 5 #include <climits> 6 #include <complex> 7 #include <fstream> 8 #include <cassert> 9 #include <cstdio> 10 #include <bitset> 11 #include <vector> 12 #include <deque> 13 #include <queue> 14 #include <stack> 15 #include <ctime> 16 #include <set> 17 #include <map> 18 #include <cmath> 19 20 using namespace std; 21 #define fr first 22 #define sc second 23 #define cl clear 24 #define BUG puts("here!!!") 25 #define W(a) while(a--) 26 #define pb(a) push_back(a) 27 #define Rint(a) scanf("%d", &a) 28 #define Rll(a) scanf("%I64d", &a) 29 #define Rs(a) scanf("%s", a) 30 #define Cin(a) cin >> a 31 #define FRead() freopen("in", "r", stdin) 32 #define FWrite() freopen("out", "w", stdout) 33 #define Rep(i, len) for(int i = 0; i < (len); i++) 34 #define For(i, a, len) for(int i = (a); i < (len); i++) 35 #define Cls(a) memset((a), 0, sizeof(a)) 36 #define Clr(a, p) memset((a), (p), sizeof(a)) 37 #define Full(a) memset((a), 0x7f7f7f, sizeof(a)) 38 #define lrt rt << 1 39 #define rrt rt << 1 | 1 40 #define pi 3.14159265359 41 #define RT return 42 #define lowbit(p) p & (-p) 43 #define onenum(p) __builtin_popcount(p) 44 typedef long long LL; 45 typedef long double LD; 46 typedef unsigned long long ULL; 47 typedef pair<int, int> pii; 48 typedef pair<string, int> psi; 49 typedef pair<LL, LL> pll; 50 typedef map<string, int> msi; 51 typedef vector<int> vi; 52 typedef vector<LL> vl; 53 typedef vector<vl> vvl; 54 typedef vector<bool> vb; 55 56 typedef struct Edge { 57 int v, w; 58 Edge() {} 59 Edge(int vv, int ww) : v(vv), w(ww) {} 60 }Edge; 61 const int maxn = 10100; 62 int n, k; 63 int depth[maxn]; //点的深度 64 int siz[maxn]; //以该点为树根,子树的点数 65 int fa[maxn]; //父亲节点编号 66 int son[maxn]; //重儿子编号 67 int top[maxn]; //点所在的重链的顶端节点 68 int p[maxn]; //点与其父亲节点的连边在线段树中的位置 69 int pos; 70 vector<Edge> G[maxn]; 71 char cmd[15]; 72 73 int dfs1(int p, int u, int d) { 74 siz[u] = 1; depth[u] = d; fa[u] = p; 75 Rep(i, G[u].size()) { 76 int& v = G[u][i].v; 77 if(v == p) continue; 78 siz[u] += dfs1(u, v, d+1); 79 if(son[u] == -1 || siz[v] > siz[son[u]]) { 80 son[u] = v; 81 } 82 } 83 return siz[u]; 84 } 85 86 void dfs2(int u, int tp) { 87 top[u] = tp; p[u] = ++pos; 88 if(son[u] != -1) dfs2(son[u], top[u]); 89 Rep(i, G[u].size()) { 90 int& v = G[u][i].v; 91 if(v != son[u] && v != fa[u]) { 92 dfs2(v, v); 93 } 94 } 95 } 96 97 #define lson l, m, rt << 1 98 #define rson m + 1, r, rt << 1 | 1 99 int sum[maxn<<2]; 100 101 void pushUP(int rt) { 102 sum[rt] = max(sum[rt<<1], sum[rt<<1|1]); 103 } 104 105 void build(int l, int r, int rt) { 106 sum[rt] = 0; 107 if(l == r) return; 108 int m = (l + r) >> 1; 109 build(lson); 110 build(rson); 111 pushUP(rt); 112 } 113 114 void update(int p, int x, int l, int r, int rt) { 115 if(l == r) { 116 sum[rt] = x; 117 return; 118 } 119 int m = (l + r) >> 1; 120 if(p <= m) update(p, x, lson); 121 else update(p, x, rson); 122 pushUP(rt); 123 } 124 125 int query(int L, int R, int l, int r, int rt) { 126 if(L <= l && r <= R) return sum[rt]; 127 int m = (l + r) >> 1; 128 int ret = 0; 129 if(L <= m) ret = max(ret, query(L, R, lson)); 130 if(R > m) ret = max(ret, query(L, R, rson)); 131 return ret; 132 } 133 134 int find(int u, int v) { 135 int f1 = top[u], f2 = top[v]; 136 int tmp = 0; 137 while(f1 != f2) { 138 if(depth[f1] < depth[f2]) { 139 swap(f1, f2); 140 swap(u, v); 141 } 142 tmp = max(tmp, query(p[f1], p[u], 1, pos, 1)); 143 u = fa[f1]; 144 f1 = top[u]; 145 } 146 if(u == v) return tmp; 147 if(depth[u] > depth[v]) swap(u, v); 148 return max(tmp, query(p[son[u]], p[v], 1, pos, 1)); 149 } 150 151 int e[maxn][3]; 152 153 signed main() { 154 // FRead(); 155 int T, u, v, w; 156 Rint(T); 157 W(T) { 158 Rint(n); 159 For(i, 1, n+5) G[i].clear(); 160 Cls(siz); Cls(depth); Clr(son, -1); Clr(fa, -1); pos = 0; Cls(sum); 161 Rep(i, n-1) { 162 Rint(u); Rint(v); Rint(w); 163 G[u].push_back(Edge(v, w)); 164 G[v].push_back(Edge(u, w)); 165 e[i+1][0] = u; e[i+1][1] = v; e[i+1][2] = w; 166 } 167 dfs1(-1, 1, 0); 168 dfs2(1, 1); 169 build(1, pos, 1); 170 For(i, 1, n) { 171 u = e[i][0]; v = e[i][1]; w = e[i][2]; 172 if(depth[u] > depth[v]) { 173 swap(e[i][0], e[i][1]); 174 swap(u, v); 175 } 176 update(p[v], w, 1, pos, 1); 177 } 178 while(~Rs(cmd) && cmd[0] != ‘D‘) { 179 Rint(u); Rint(v); 180 if(cmd[0] == ‘Q‘) { 181 printf("%d\n", find(u, v)); 182 } 183 if(cmd[0] == ‘C‘) { 184 update(p[e[u][1]], v, 1, pos, 1); 185 } 186 } 187 } 188 RT 0; 189 }
以上是关于[SPOJ]Query on a tree(树链剖分,线段树)的主要内容,如果未能解决你的问题,请参考以下文章
SPOJ QTREE Query on a tree ——树链剖分 线段树
[SPOJ]Query on a tree(树链剖分,线段树)
SPOJ QTREE Query on a Tree树链剖分模板题