zoukankan      html  css  js  c++  java
  • Count on a tree SPOJ

    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
    ", 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
    ", vv[ans-1]);
    215     }
    216     return 0;
    217 }
    View Code
  • 相关阅读:
    SQL语言
    数组的指针
    Java泛型
    python面向对象(下)
    Java枚举类enum
    理解Java的GC日志
    python生成器
    Java并发编程之ThreadLocal类
    python面向对象(上)
    Java并发编程之闭锁简介
  • 原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/10121047.html
Copyright © 2011-2022 走看看