zoukankan      html  css  js  c++  java
  • bzoj1803: Spoj1487 Query on a tree III

    Description

    You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node whose label is k-th largest in the subtree of the node x. Assume no two nodes have the same labels.

    Input

    The first line contains one integer n (1 <= n <= 10^5). The next line contains n integers li (0 <= li <= 109) which denotes the label of the i-th node. Each line of the following n - 1 lines contains two integers u, v. They denote there is an edge between node u and node v. Node 1 is the root of the tree. The next line contains one integer m (1 <= m <= 10^4) which denotes the number of the queries. Each line of the next m contains two integers x, k. (k <= the total node number in the subtree of x)

    Output

    For each query (x, k), output the index of the node whose label is the k-th largest in the subtree of the node x.
    按dfs序建可持久化线段树,子树对应连续的区间,可以直接查询kth
    #include<cstdio>
    inline int _int(){
        int x=0,c=getchar();
        while(c>57||c<48)c=getchar();
        while(c>47&&c<58)x=x*10+c-48,c=getchar();
        return x;
    }
    const int N=100010;
    int n;
    int v[N],rt[N],id[N],idr[N],idp=0;
    int es[N*2],enx[N*2],e0[N],ep=2;
    int ch[N*33][2],sz[N*33],ids[N*33],p=0;
    int ins(int w,int x,int id){
        int u=++p,u0=u;
        for(int i=30;~i;i--){
            int d=x>>i&1;
            ch[u][d^1]=ch[w][d^1];
            sz[u=ch[u][d]=++p]=sz[w=ch[w][d]]+1;
        }
        ids[u]=id;
        return u0;
    }
    void dfs(int w,int pa){
        id[w]=++idp;
        rt[idp]=ins(rt[idp-1],v[w],w);
        for(int i=e0[w];i;i=enx[i]){
            int u=es[i];
            if(u!=pa)dfs(u,w);
        }
        idr[w]=idp;
    }
    void kth(int w1,int w2,int k){
        for(int i=30;~i;i--){
            int s=sz[ch[w1][0]]-sz[ch[w2][0]];
            if(s<k){
                k-=s;
                w1=ch[w1][1];
                w2=ch[w2][1];
            }else{
                w1=ch[w1][0];
                w2=ch[w2][0];
            }
        }
        printf("%d
    ",ids[w1]);
    }
    int main(){
        n=_int();
        for(int i=1;i<=n;i++)v[i]=_int();
        for(int i=1;i<n;i++){
            int a=_int(),b=_int();
            es[ep]=b;enx[ep]=e0[a];e0[a]=ep++;
            es[ep]=a;enx[ep]=e0[b];e0[b]=ep++;
        }
        dfs(1,0);
        for(int q=_int();q;q--){
            int x=_int();
            kth(rt[idr[x]],rt[id[x]-1],_int());
        }
        return 0;
    }
  • 相关阅读:
    python---模块与包
    python---迭代器与生成器
    python---装饰器
    Python---函数
    Python---文件操作
    Python---数据类型
    浅谈UBUNTU
    java 键盘输入多种方法
    动态规划解最长公共子序列问题
    线段树
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5622282.html
Copyright © 2011-2022 走看看