1. 程式人生 > >hdu3078(lca / RMQ在線)

hdu3078(lca / RMQ在線)

ace ++ targe tdi clas != quest pan color

題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=3078

題意: 給出一棵 n 個點的帶點權值的樹, 接下來有 q 組形如 k, x, y 的輸入, 若 k == 0 則將 x 點的權值替換成 y, 否則輸出 x 到 y 之間頂點地 k 大的權值.

思路: 用一個數組 val 記錄一下每個頂點的權值, 對於k == 0, 直接令 val[x] = y 即可 .

對於詢問, 可以先求出 lca, 再記錄一下路徑上的頂點的權值, sort 一下, 輸出第 k 大的即可.

代碼:

技術分享
 1 #include <iostream>
 2 #include <stdio.h>
 3
#include <math.h> 4 #include <string.h> 5 #include <algorithm> 6 #include <vector> 7 using namespace std; 8 9 const int MAXN = 8e4 + 10; 10 vector<int> vt[MAXN]; 11 int dp[MAXN << 1][30]; 12 int first[MAXN], ver[MAXN << 1], deep[MAXN << 1]; 13 int
pre[MAXN], val[MAXN], yy[MAXN], ip = 0, indx = 0; 14 15 bool cmp(int x, int y){ 16 return x > y; 17 } 18 19 void dfs(int u, int h, int fa){ 20 pre[u] = fa; 21 ver[++indx] = u; 22 deep[indx] = h; 23 first[u] = indx; 24 for(int i = 0; i < vt[u].size(); i++){ 25 int
v = vt[u][i]; 26 if(v != fa){ 27 dfs(v, h + 1, u); 28 ver[++indx] = u; 29 deep[indx] = h; 30 } 31 } 32 } 33 34 void ST(int n){ 35 for(int i = 1; i <= n; i++){ 36 dp[i][0] = i; 37 } 38 for(int j = 1; (1 << j) <= n; j++){ 39 for(int i = 1; i + (1 << j) - 1 <= n; i++){ 40 int x = dp[i][j - 1], y = dp[i + (1 << (j - 1))][j -1]; 41 dp[i][j] = deep[x] < deep[y] ? x : y; 42 } 43 } 44 } 45 46 int RMQ(int l, int r){ 47 int len = log2(r - l + 1); 48 int x = dp[l][len], y = dp[r - (1 << len) + 1][len]; 49 return deep[x] < deep[y] ? x : y; 50 } 51 52 int LCA(int x, int y){ 53 int l = first[x]; 54 int r = first[y]; 55 if(l > r) swap(l, r); 56 int pos = RMQ(l, r); 57 return ver[pos]; 58 } 59 60 void path(int x, int root, int &pos){ 61 while(x != root && x != -1){ 62 yy[pos++] = val[x]; 63 x = pre[x]; 64 } 65 } 66 67 void solve(int x, int y, int k){ 68 int pos = 0, lca = LCA(x, y); 69 path(x, lca, pos); 70 path(y, lca, pos); 71 yy[pos++] = val[lca]; 72 if(pos < k) puts("invalid request!"); 73 else{ 74 sort(yy, yy + pos, cmp);//註意是從大到小的第 k 大!!!!!!!!! 75 printf("%d\n", yy[k - 1]); 76 } 77 } 78 79 int main(void){ 80 int n, q, x, y, op; 81 scanf("%d%d", &n, &q); 82 for(int i = 1; i <= n; i++){ 83 scanf("%d", &val[i]); 84 } 85 for(int i = 1; i < n; i++){ 86 scanf("%d%d", &x, &y); 87 vt[x].push_back(y); 88 vt[y].push_back(x); 89 } 90 dfs(1, 1, -1); 91 ST(indx); 92 while(q--){ 93 scanf("%d%d%d", &op, &x, &y); 94 if(!op) val[x] = y; 95 else solve(x, y, op); 96 } 97 return 0; 98 }
View Code

hdu3078(lca / RMQ在線)