zoukankan      html  css  js  c++  java
  • 【BZOJ 2588】Count on a tree

    Description

    给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。
     

    Input

    第一行两个整数N,M。
    第二行有N个整数,其中第i个整数表示点i的权值。
    后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
    最后M行每行两个整数(u,v,k),表示一组询问。
     

    Output

     
    M行,表示每个询问的答案。

    Sample 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
    0 5 2
    10 5 3
    11 5 4
    110 8 2

    Sample Output

    2
    8
    9
    105
    7

    HINT

    N,M<=100000

    暴力自重。。。
     
     
     
    分析:
      可持久化线段树,以父亲的版本为基础创建儿子的版本,结合LCA就可以了。(最后多了个 居然给我格式错误QAQ)
     
    代码:
      1 #include <cstdio>
      2 #include <algorithm>
      3 
      4 const int maxn = 500000;
      5 const int maxm = 2000000;
      6 
      7 int et[maxn], ep[maxn], last[maxn], en;
      8 int ch[maxm][2], Count[maxm];
      9 int root[maxm], size;
     10 int n, m, u, v, w, lca, ans;
     11 int deep[maxn], fa[maxn][20];
     12 int num[maxn], id[maxn], back[maxn];
     13 
     14 void ins (int a, int b)
     15 {
     16     en++;
     17     ep[en] = last[a];
     18     last[a] = en;
     19     et[en] = b;
     20 }
     21 
     22 #define MID (left + (right - left >> 1))
     23 
     24 
     25 int modify (int left, int right, int pos, int prev)
     26 {
     27     int i = ++size;
     28     if (left < right)
     29     {
     30         int c = pos > MID;
     31         ch[i][!c] = ch[prev][!c];
     32         c ? left = MID + 1 : right = MID;
     33         ch[i][c] = modify (left, right, pos, ch[prev][c]);
     34         Count[i] = Count[ch[i][0]] + Count[ch[i][1]];
     35     }else Count[i] = 1;
     36     return i;
     37 }
     38 
     39 #define LEFTSIZE (Count[ch[l1][0]] + Count[ch[l2][0]] - Count[ch[e1][0]] - Count[ch[e2][0]])
     40 
     41 int query (int left, int right, int e1, int e2, int l1, int l2, int k)
     42 {
     43     if (left == right) return num[id[left]];
     44     int c = k > LEFTSIZE;
     45     c ? left = MID + 1 : right = MID;
     46     return query (left, right, ch[e1][c], ch[e2][c], ch[l1][c], ch[l2][c], c ? k - LEFTSIZE : k);
     47 }
     48 
     49 bool cmp (int a, int b)
     50 {
     51     return num[a] < num[b];
     52 }
     53 
     54 void dfs (int i, int p)
     55 {
     56     deep[i] = deep[p] + 1;
     57     fa[i][0] = p;
     58     for (int b = 0; fa[i][b]; b++)
     59         fa[i][b + 1] = fa[fa[i][b]][b];
     60     root[i] = modify (1, n, back[i], root[p]);
     61     for (int e = last[i]; e; e = ep[e])
     62         if (deep[et[e]] == 0) dfs (et[e], i);
     63 }
     64 
     65 int find (int i, int j)
     66 {
     67     int k, b;
     68     if (deep[i] > deep[j])
     69         i ^= j, j ^= i, i ^= j;
     70     for (k = deep[j] - deep[i], b = 0; k; k >>= 1, b++)
     71         k & 1 ? j = fa[j][b] : 1;
     72     if (i == j) return i;
     73     for (b = 0; fa[i][b] != fa[j][b]; b++);
     74     for (b--; ~b; b--) if (fa[i][b] != fa[j][b]) i = fa[i][b], j = fa[j][b];
     75     return fa[i][0];
     76 }
     77 
     78 int main ()
     79 {
     80     scanf ("%d %d", &n, &m);
     81     for (int i = 1; i <= n; i++)
     82         scanf ("%d", &num[i]), id[i] = i;
     83     std::sort (id + 1, id + n + 1, cmp);
     84     for (int i = 1; i <= n; i++)
     85         back[id[i]] = i;
     86     for (int i = 1; i < n; i++)
     87     {
     88         scanf ("%d %d", &u, &v);
     89         int flag = last[id[1]] > 0;
     90         ins (u, v); ins (v, u);
     91     }
     92     dfs (1, 0);
     93     ans = 0;
     94     for (int i = 0; i < m; i++)
     95     {
     96         scanf ("%d %d %d", &u, &v, &w);
     97         u ^= ans;
     98         lca = find (u, v);
     99         ans = query (1, n, root[fa[lca][0]], root[lca], root[u], root[v], w);
    100         if (i) printf ("
    ");
    101         printf ("%d", ans);
    102     }
    103 }
  • 相关阅读:
    MySQL · 引擎特性 · InnoDB 事务锁简介
    锁大全与 GDB调试
    docker(4):coreos+docker+rancher真厉害
    TIDB ---NEW SQL
    Linux的内存回收和交换
    TLS握手优化详解
    北风网JAVA 大数据培训
    MySQL 5.7 深度解析: JSON数据类型使用
    MySQL 5.7 深度解析: 临时表空间
    在Linux最大打开文件数限制下 MySQL 对参数的调整
  • 原文地址:https://www.cnblogs.com/lightning34/p/4389789.html
Copyright © 2011-2022 走看看