zoukankan      html  css  js  c++  java
  • hdu3078(lca / RMQ在线)

    题目链接: 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
    ", 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
  • 相关阅读:
    Sum Root to Leaf Numbers 解答
    459. Repeated Substring Pattern
    71. Simplify Path
    89. Gray Code
    73. Set Matrix Zeroes
    297. Serialize and Deserialize Binary Tree
    449. Serialize and Deserialize BST
    451. Sort Characters By Frequency
    165. Compare Version Numbers
    447. Number of Boomerangs
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7210643.html
Copyright © 2011-2022 走看看