• Count on a tree 树上区间第K小


    Count on a tree

    题意:求路径 u到v上的 第k小的权重。

    题解:先DFS建数, 然后对于每个节点往上跑出一颗主席树, 然后每次更新。 查询的时候, u, v, k, 找到  z = lca(u,v) , p = anc[z][0], 然后对于这条路上左边子节点的个数就可以被表示为u,v的树- z,p的树上的值。

    然后主要是LCA不怎么用写搓了, 找了好久的bug。 汗。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define max3(a,b,c) max(a,max(b,c))
     10 #define min3(a,b,c) min(a,min(b,c))
     11 typedef pair<int,int> pll;
     12 const int INF = 0x3f3f3f3f;
     13 const LL mod =  (int)1e9+7;
     14 const int N = 1e5 + 100;
     15 const int M = 5e6 + 100;
     16 vector<int> son[N];
     17 int lson[M], rson[M], cnt[M];
     18 int anc[N][20];
     19 int tot, t;
     20 int a[N], w[N], deep[N], root[N];
     21 int id(int x){
     22     return lower_bound(a+1, a+1+t, x) - a;
     23 }
     24 int Build(int l, int r){
     25     int now = ++tot;
     26     cnt[now] = 0;
     27     if(l < r){
     28         int m = l+r >> 1;
     29         lson[now] = Build(l, m);
     30         rson[now] = Build(m+1, r);
     31     }
     32     return now;
     33 }
     34 int Update(int l, int r, int pre, int c, int v){
     35     int now = ++tot;
     36     cnt[now] = cnt[pre] + v;
     37     if(l < r){
     38         int m = l+r >> 1;
     39         if(c <= m){
     40             rson[now] = rson[pre];
     41             lson[now] = Update(l, m, lson[pre], c, v);
     42         }
     43         else {
     44             lson[now] = lson[pre];
     45             rson[now] = Update(m+1, r, rson[pre], c, v);
     46         }
     47     }
     48     return now;
     49 }
     50 
     51 void dfs(int o, int u){
     52     deep[u] = deep[o] + 1;
     53     root[u] = Update(1, t, root[o], id(w[u]), 1);
     54     for(int i = 0; i < son[u].size(); i++){
     55         int v = son[u][i];
     56         if(v == o) continue;
     57         anc[v][0] = u;
     58         for(int j = 1; j < 19; j++) anc[v][j] = anc[anc[v][j-1]][j-1];
     59         dfs(u, v);
     60     }
     61 }
     62 int lca(int u, int v){
     63     if(deep[u] < deep[v]) swap(u, v);
     64     for(int i = 19; i >= 0; i--)
     65         if(deep[anc[u][i]] >= deep[v]) u = anc[u][i];
     66     if(u == v) return v;
     67     for(int i = 19; i >= 0; i--)
     68         if(anc[u][i] != anc[v][i])
     69             u = anc[u][i], v = anc[v][i];
     70     return anc[u][0];
     71 }
     72 int Query(int l, int r, int c1, int c2, int d1, int d2, int k){
     73     if(l == r) return a[l];
     74     int m = l+r >> 1;
     75     int num = cnt[lson[c1]] + cnt[lson[c2]] - cnt[lson[d1]] - cnt[lson[d2]];
     76     if(num >= k) return Query(l, m, lson[c1], lson[c2], lson[d1], lson[d2], k);
     77     else return Query(m+1, r, rson[c1], rson[c2], rson[d1], rson[d2], k-num);
     78 }
     79 int main(){
     80     int n, q, u, v, k, p, z;
     81     scanf("%d%d", &n, &q);
     82     for(int i = 1; i <= n; i++){
     83         scanf("%d", &w[i]);
     84         a[i] = w[i];
     85     }
     86     for(int i = 1; i < n; i++){
     87         scanf("%d%d", &u, &v);
     88         son[u].pb(v);
     89         son[v].pb(u);
     90     }
     91     sort(a+1, a+1+n);
     92     for(int i = 1; i <= n; i++) a[++t] = a[i];
     93     root[0] = Build(1, t);
     94     dfs(0, 1);
     95     while(q--){
     96         scanf("%d%d%d", &u, &v, &k);
     97         z = lca(u, v);
     98         p = anc[z][0];
     99         printf("%d
    ", Query(1, t, root[u], root[v], root[z], root[p], k));
    100     }
    101     return 0;
    102 }
    Count on a tree
  • 相关阅读:
    urllib2使用总结
    Scrapy简介
    python3使用多代理访问网站
    ISO9000 质量管理和质量保证系列国际标准
    怎样花两年时间去面试一个人
    Robot Framework 快速入门_中文版
    PMP项目经理认证
    Scrapy安装介绍
    批处理写的俄罗斯方块
    TL9000 电信业质量体系管理标准
  • 原文地址:https://www.cnblogs.com/MingSD/p/9096150.html
Copyright © 2020-2023  润新知