1. 程式人生 > >Count on a tree SPOJ - COT (主席樹,LCA)

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      '!;;;;;;;;[email protected]###&|;;|%!;!$|;;;;|&&;.
  9      :!;;;;[email protected]&%|;;;;;;;;;|!::!!:::;!$%;!$%`    '!%&#########@$!:.
 10      ;!;;!!;;;;;|$$&@##$;;;::'''''::;;;;|&|%@$|;;;;;;;;;;;;;;;;!$;
 11      ;|;;;;;;;;;;;;;;;;;;!%@#####&!:::;!;;;;;;;;;;!&####@%!;;;;$%`
 12     `!!;;;;;;;;;;!|%%|!!;::;;|@##%|$|;;;;;;;;;;;;!|%$#####%;;;%&;
 13     :@###&!:;;!!||%%%%%|!;;;;;||;;;;||!$&&@@%;;;;;;;|$$##$;;;%@|
 14     ;|::;;;;;;;;;;;;|&&$|;;[email protected]&$!;;;;!;;;;;;;;;;;;;;;;!%|;;;%@%.
 15    `!!;;;;;;;!!!!;;;;;[email protected]@@&&&&&@$!;!%|;;;;!||!;;;;;!|%%%!;;%@|.
 16 %&&$!;;;;;!;;;;;;;;;;;|$&&&&&&&&&@@%!%%;!||!;;;;;;;;;;;;;$##!
 17 !%;;;;;;!%!:;;;;;;;;;;!$&&&&&&&&&&@##&%|||;;;!!||!;;;;;;;$&:
 18 ':|@###%;:;;;;;;;;;;;;!%$&&&&&&@@$!;;;;;;;!!!;;;;;%&!;;|&%.
 19  [email protected]|;;;;;;;;;;;;;;;;;;|%|$&&$%&&|;;;;;;;;;;;;!;;;;;!&@@&'
 20   .:%#&!;;;;;;;;;;;;;;!%|$$%%&@%;;;;;;;;;;;;;;;;;;;!&@:
 21   .%$;;;;;;;;;;;;;;;;;;|[email protected]&|;;;;;;;;;;;;;;;;;;;;%@%.
 22     !&!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|@#;
 23      `%$!;;;;;;;;;;;[email protected]|;;;;;;;;;;;;;;;;;;;;;;;;!%[email protected]#@|.
 24        .|@%!;;;;;;;;;!$&%||;;;;;;;;;;;;;;;;;!%[email protected]#|.
 25            ;&$!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%#####|.
 26            |##$|!;;;;;;::'':;;;;;;;;;;;;;!%[email protected]#@;
 27           ;@&|;;;;;;;::'''''':;;;;;;;|$&@###@|`
 28         .%##@|;;;;:::''''''''''::;!%&##$'
 29       `$##@[email protected]@&|!!;;;:'''''::::;;;;;|&#%.
 30     ;&@##&$%!;;;;;;::''''''''::;!|%[email protected]#@&@@:
 31      .%@&$$|;;;;;;;;;;:'''':''''::;;;%@#@@#%.
 32     :@##@###@$$$$$|;;:'''':;;!!;;;;;;!$#@@#$;`
 33      `%@$$|;;;;;;;;:'''''''::;;;;|%$$|!!&###&'
 34      |##&%!;;;;;::''''''''''''::;;;;;;;[email protected]&:`!'
 35     :;[email protected]$|;;;;;;;::''''''''''':;;;;;;;;!%&@$:                [email protected]#$'
 36       |##@@&%;;;;;::''''''''':;;;;;;;!%&@#@$%:            '%%!%&;
 37       |&%!;;;;;;;%$!:''''''':|%!;;;;;;;;|&@%||`         '%$|!%&;
 38       |@%!;;!!;;;||;:'''''':;%$!;;;;!%%%&#&%$&:        .|%;:!&%`
 39       [email protected]&%;;;;;;;||;;;:''::;;%$!;;;;;;;|&@%;!$;       `%&%!!$&:
 40       '$$|;!!!!;;||;;;;;;;;;;%%;;;;;;;|@@|!$##;      !$!;:!$&:
 41        |#&|;;;;;;!||;;;;;;;;!%|;;;;!$##$;;;;|%'   `%$|%%;|&$'
 42         |&%!;;;;;;|%;;;;;;;;$$;;;;;;|&&|!|%&&;  .:%&$!;;;:[email protected]!
 43         `%#&%!!;;;;||;;;;;!$&|;;;!%%%@&!;;;!!;;;|%!;;%@$!%@!
 44         !&!;;;;;;;;;||;;%&!;;;;;;;;;%@&!;;!&$;;;|&%;;;%@%`
 45        '%|;;;;;;;;!!|$|%&%;;;;;;;;;;|&#&|!!||!!|%[email protected]@|'
 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