zoukankan      html  css  js  c++  java
  • BZOJ1803Spoj1487 Query on a tree III——主席树

    题目大意

      给一棵有点权的n个点的有根树,保证任意两点的点权不同,m次询问每次询问x的子树中权值第k大的点。

    输入

      先输入n,然后每个点点权,再输入n-1行每行两个数x,y代表x和y相连,再输入m,之后m次询问,每行两个数x,k。

      主席树,随便找一个点为根,再dfs出树的dfs序,按dfs序建每一时刻主席树,利用主席树查询x子树区间第k大。

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    inline char _read()
    {
        static char buf[100000],*p1=buf,*p2=buf;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int read()
    {
        int x=0,f=1;char ch=_read();
        while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=_read();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=_read();}
        return x*f;
    }
    int n,m;
    int x,y;
    int tot;
    int num;
    int cnt;
    int q[100010];
    int s[100010];
    int t[100010];
    int v[100010];
    int to[200010];
    int ls[4000010];
    int rs[4000010];
    int next[200010];
    int head[100010];
    int root[100010];
    int sum[4000010];
    map<int,int>b;
    void add(int x,int y)
    {
        tot++;
        next[tot]=head[x];
        head[x]=tot;
        to[tot]=y;
    }
    void dfs(int x,int fa)
    {
        s[x]=++num;
        q[num]=x;
        for(int i=head[x];i;i=next[i])
        {
            if(to[i]!=fa)
            {
                dfs(to[i],x);
            }
        }
        t[x]=num;
    }
    int updata(int pre,int l,int r,int v)
    {
        int rt=++cnt;
        if(l==r)
        {
            sum[rt]=sum[pre]+1;
            return rt;
        }
        ls[rt]=ls[pre];
        rs[rt]=rs[pre];
        sum[rt]=sum[pre]+1;
        int mid=(l+r)>>1;
        if(v<=mid)
        {
            ls[rt]=updata(ls[pre],l,mid,v);
        }
        else
        {
            rs[rt]=updata(rs[pre],mid+1,r,v);
        }
        return rt;
    }
    int query(int x,int y,int l,int r,int k)
    {
        if(l==r)
        {
            return b[l];
        }
        int val=sum[ls[y]]-sum[ls[x]];
        int mid=(l+r)>>1;
        if(val<k)
        {
            return query(rs[x],rs[y],mid+1,r,k-val);
        }
        else
        {
            return query(ls[x],ls[y],l,mid,k);
        }
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
        {
            v[i]=read();
            b[v[i]]=i;
        }
        for(int i=1;i<n;i++)
        {
            x=read();
            y=read();
            add(x,y);
            add(y,x);
        }
        dfs(1,0);
        for(int i=1;i<=num;i++)
        {
            root[i]=updata(root[i-1],0,1e9,v[q[i]]);
        }
        m=read();
        for(int i=1;i<=m;i++)
        {
            x=read();
            y=read();
            printf("%d
    ",query(root[s[x]-1],root[t[x]],0,1e9,y));
        }
    }
  • 相关阅读:
    思念
    空白
    curl json string with variable All In One
    virtual scroll list All In One
    corejs & RegExp error All In One
    socket.io All In One
    vue camelCase vs PascalCase vs kebabcase All In One
    element ui 表单校验,非必填字段校验 All In One
    github 定时任务 UTC 时间不准确 bug All In One
    input range & color picker All In One
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/9449809.html
Copyright © 2011-2022 走看看