Count on a tree SPOJ - COT (主席树,LCA)

You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer weight.

We will ask you to perform the following operation:

  • u v k : ask for the kth minimum weight on the path from node u to node v

Input

In the first line there are two integers N and M. (N, M <= 100000)

In the second line there are N integers. The ith integer denotes the weight of the ith node.

In the next N-1 lines, each line contains two integers u v, which describes an edge (uv).

In the next M lines, each line contains three integers u v k, which means an operation asking for the kth minimum weight on the path from node u to node v.

Output

For each operation, print its result.

Example

Input:
8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
2 5 2
2 5 3
2 5 4
7 8 2 
Output:
2
8
9
105

给出一棵树,每个点都自己的权重,然后给出树上的边,要求从节点 u 到节点 v 路径上的第 k 小的权重的大小。
因为权重可能很大,所以需要离散化。
主席树求区间第 k 小维护的是权值线段树的前缀和,然后通过区间相减得到查询区间的权值线段树
所以树形结构的第 k 小维护的也是权值线段树的前缀和,这里的前缀和表示从第 i 个结点到根的前缀和,比如样例的树是

那么我们用主席树把这八个结点维护成这个样子

那么要得到其中两个点(u,v)之间的树形结构,就可以看成 TREE(u) + TREE(v) - TREE(lca(u,v))- TREE(fa(lca(u,v))),把查询看成四棵树之间的相加相减,然后在求一下lca(u,v)就可以了,这里我比较懒直接用在线的写了 

  1 /*
  2           .
  3          ';;;;;.
  4         '!;;;;;;!;`
  5        '!;|&#@|;;;;!:
  6       `;;!&####@|;;;;!:
  7      .;;;!&@$$%|!;;;;;;!'.`:::::'.
  8      '!;;;;;;;;!$@###&|;;|%!;!$|;;;;|&&;.
  9      :!;;;;!$@&%|;;;;;;;;;|!::!!:::;!$%;!$%`    '!%&#########@$!:.
 10      ;!;;!!;;;;;|$$&@##$;;;::'''''::;;;;|&|%@$|;;;;;;;;;;;;;;;;!$;
 11      ;|;;;;;;;;;;;;;;;;;;!%@#####&!:::;!;;;;;;;;;;!&####@%!;;;;$%`
 12     `!!;;;;;;;;;;!|%%|!!;::;;|@##%|$|;;;;;;;;;;;;!|%$#####%;;;%&;
 13     :@###&!:;;!!||%%%%%|!;;;;;||;;;;||!$&&@@%;;;;;;;|$$##$;;;%@|
 14     ;|::;;;;;;;;;;;;|&&$|;;!$@&$!;;;;!;;;;;;;;;;;;;;;;!%|;;;%@%.
 15    `!!;;;;;;;!!!!;;;;;$@@@&&&&&@$!;!%|;;;;!||!;;;;;!|%%%!;;%@|.
 16 %&&$!;;;;;!;;;;;;;;;;;|$&&&&&&&&&@@%!%%;!||!;;;;;;;;;;;;;$##!
 17 !%;;;;;;!%!:;;;;;;;;;;!$&&&&&&&&&&@##&%|||;;;!!||!;;;;;;;$&:
 18 ':|@###%;:;;;;;;;;;;;;!%$&&&&&&@@$!;;;;;;;!!!;;;;;%&!;;|&%.
 19  !@|;;;;;;;;;;;;;;;;;;|%|$&&$%&&|;;;;;;;;;;;;!;;;;;!&@@&'
 20   .:%#&!;;;;;;;;;;;;;;!%|$$%%&@%;;;;;;;;;;;;;;;;;;;!&@:
 21   .%$;;;;;;;;;;;;;;;;;;|$$$$@&|;;;;;;;;;;;;;;;;;;;;%@%.
 22     !&!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|@#;
 23      `%$!;;;;;;;;;;;$@|;;;;;;;;;;;;;;;;;;;;;;;;!%$@#@|.
 24        .|@%!;;;;;;;;;!$&%||;;;;;;;;;;;;;;;;;!%$$$$$@#|.
 25            ;&$!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%#####|.
 26            |##$|!;;;;;;::'':;;;;;;;;;;;;;!%$$$@#@;
 27           ;@&|;;;;;;;::'''''':;;;;;;;|$&@###@|`
 28         .%##@|;;;;:::''''''''''::;!%&##$'
 29       `$##@$$@@&|!!;;;:'''''::::;;;;;|&#%.
 30     ;&@##&$%!;;;;;;::''''''''::;!|%$@#@&@@:
 31      .%@&$$|;;;;;;;;;;:'''':''''::;;;%@#@@#%.
 32     :@##@###@$$$$$|;;:'''':;;!!;;;;;;!$#@@#$;`
 33      `%@$$|;;;;;;;;:'''''''::;;;;|%$$|!!&###&'
 34      |##&%!;;;;;::''''''''''''::;;;;;;;!$@&:`!'
 35     :;!@$|;;;;;;;::''''''''''':;;;;;;;;!%&@$:                !@#$'
 36       |##@@&%;;;;;::''''''''':;;;;;;;!%&@#@$%:            '%%!%&;
 37       |&%!;;;;;;;%$!:''''''':|%!;;;;;;;;|&@%||`         '%$|!%&;
 38       |@%!;;!!;;;||;:'''''':;%$!;;;;!%%%&#&%$&:        .|%;:!&%`
 39       !@&%;;;;;;;||;;;:''::;;%$!;;;;;;;|&@%;!$;       `%&%!!$&:
 40       '$$|;!!!!;;||;;;;;;;;;;%%;;;;;;;|@@|!$##;      !$!;:!$&:
 41        |#&|;;;;;;!||;;;;;;;;!%|;;;;!$##$;;;;|%'   `%$|%%;|&$'
 42         |&%!;;;;;;|%;;;;;;;;$$;;;;;;|&&|!|%&&;  .:%&$!;;;:!$@!
 43         `%#&%!!;;;;||;;;;;!$&|;;;!%%%@&!;;;!!;;;|%!;;%@$!%@!
 44         !&!;;;;;;;;;||;;%&!;;;;;;;;;%@&!;;!&$;;;|&%;;;%@%`
 45        '%|;;;;;;;;!!|$|%&%;;;;;;;;;;|&#&|!!||!!|%$@@|'
 46        .!%%&%'`|$;     :|$#%|@#&;%#%.
 47 */
 48 #include <map>
 49 #include <set>
 50 #include <list>
 51 #include <ctime>
 52 #include <cmath>
 53 #include <stack>
 54 #include <queue>
 55 #include <string>
 56 #include <vector>
 57 #include <cstdio>
 58 #include <bitset>
 59 #include <cstdlib>
 60 #include <cstring>
 61 #include <iostream>
 62 #include <algorithm>
 63 #define  lowbit(x)  x & (-x)
 64 #define  mes(a, b)  memset(a, b, sizeof a)
 65 #define  fi         first
 66 #define  se         second
 67 #define  pii        pair<int, int>
 68 #define  INOPEN     freopen("in.txt", "r", stdin)
 69 #define  OUTOPEN    freopen("out.txt", "w", stdout)
 70 
 71 typedef unsigned long long int ull;
 72 typedef long long int ll;
 73 const int    maxn = 1e5 + 10;
 74 const int    maxm = 1e5 + 10;
 75 const int    mod  = 1e9 + 7;
 76 const ll     INF  = 1e18 + 100;
 77 const int    inf  = 0x3f3f3f3f;
 78 const double pi   = acos(-1.0);
 79 const double eps  = 1e-8;
 80 using namespace std;
 81 
 82 int n, m;
 83 int cas, tol, T;
 84 
 85 struct Node {
 86     int l, r;
 87     int sum;
 88 } node[maxn * 50];
 89 int a[maxn];
 90 int rt[maxn];
 91 bool vis[maxn];
 92 int deep[maxn];
 93 int fa[maxn][30];
 94 vector<int> vec[maxn];
 95 vector<int> vv;
 96 
 97 void init() {
 98     tol = 0;
 99     mes(a, 0);
100     mes(rt, 0);
101     mes(fa, 0);
102     mes(vis, 0);
103     mes(node, 0);
104     mes(deep, 0);
105     vv.clear();
106     for(int i=1; i<=n; i++)
107         vec[i].clear();
108 }
109 
110 int getid(int x) {
111     return lower_bound(vv.begin(), vv.end(), x) - vv.begin() + 1;
112 }
113 
114 void lca_dfs(int u, int f, int d) {
115     deep[u] = d;
116     int len = vec[u].size();
117     for(int i=0; i<len; i++) {
118         int v = vec[u][i];
119         if(v == f)    continue;
120         if(fa[v][0])continue;
121         fa[v][0] = u;
122         lca_dfs(v, u, d+1);
123     }
124 }
125 
126 void lca_update() {
127     for(int j=1; (1<<j)<=n; j++) {
128         for(int i=1; i<=n; i++) {
129             fa[i][j] = fa[fa[i][j-1]][j-1];
130         }
131     }
132 }
133 
134 int lca_query(int u, int v) {
135     if(deep[u] < deep[v])    swap(u, v);
136     int f = deep[u] - deep[v];
137     for(int i=0; (1<<i)<=f; i++) {
138         if(f & (1<<i)) {
139             u = fa[u][i];
140         }
141     }
142     if(u != v) {
143         for(int i=(int)log2(n); i>=0; i--) {
144             if(fa[u][i] != fa[v][i]) {
145                 u = fa[u][i];
146                 v = fa[v][i];
147             }
148         }
149         u = fa[u][0];
150     }
151     return u;
152 }
153 
154 void hjt_update(int l, int r, int &x, int y, int pos) {
155     tol++;
156     node[tol] = node[y];
157     node[tol].sum++;
158     x = tol;
159     if(l == r)    return ;
160     int mid = (l + r) >> 1;
161     if(pos <= mid)
162         hjt_update(l, mid, node[x].l, node[y].l, pos);
163     else
164         hjt_update(mid+1, r, node[x].r, node[y].r, pos);
165 }
166 
167 void hjt_build(int u, int f) {
168 //    printf("%d %d\n", u, f);
169     hjt_update(1, n, rt[u], rt[f], getid(a[u]));
170     vis[u] = true;
171     int len = vec[u].size();
172     for(int i=0; i<len; i++) {
173         int v = vec[u][i];
174         if(vis[v])    continue;
175         if(v == f)    continue;
176         hjt_build(v, u);
177     }
178 }
179 
180 int hjt_query(int l, int r, int x, int y, int lca, int flca, int k) {
181     if(l == r)
182         return l;
183     int mid = (l + r) >> 1;
184     int sum = node[node[x].l].sum + node[node[y].l].sum - node[node[lca].l].sum - node[node[flca].l].sum;
185     if(k <= sum)
186         return hjt_query(l, mid, node[x].l, node[y].l, node[lca].l, node[flca].l, k);
187     else
188         return hjt_query(mid+1, r, node[x].r, node[y].r, node[lca].r, node[flca].r, k-sum);
189 }
190 
191 int main() {
192     scanf("%d%d", &n, &m);
193     init();
194     for(int i=1; i<=n; i++) {
195         scanf("%d", &a[i]);
196         vv.push_back(a[i]);
197     }
198     sort(vv.begin(), vv.end());
199     vv.erase(unique(vv.begin(), vv.end()), vv.end());
200     for(int i=1; i<n; i++) {
201         int u, v;
202         scanf("%d%d", &u, &v);
203         vec[u].push_back(v);
204         vec[v].push_back(u);
205     }
206     fa[1][0] = 0;
207     lca_dfs(1, 0, 1);
208     lca_update();
209     hjt_build(1, 0);
210     while(m--) {
211         int u, v, k;
212         scanf("%d%d%d", &u, &v, &k);
213         int ans = hjt_query(1, n, rt[u], rt[v], rt[lca_query(u, v)], rt[fa[lca_query(u, v)][0]], k);
214         printf("%d\n", vv[ans-1]);
215     }
216     return 0;
217 }
View Code

猜你喜欢

转载自www.cnblogs.com/H-Riven/p/10121047.html