zoukankan      html  css  js  c++  java
  • BZOJ 1803 Query on a tree III

    树上主席树。

    我靠这是第k小吧。。。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxv 200050
    #define maxe 300500
    using namespace std;
    int n,a[maxv],b[maxv],len,x,y,g[maxv],q,nume=0,kr[maxv];
    int ls[maxv*18],rs[maxv*18],root[maxv],tot=0,sum[maxv*18];
    int w[maxv],cnt=0,mx[maxv],fw[maxv];
    struct edge
    {
        int v,nxt;
    }e[maxe];
    void addedge(int u,int v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void divide()
    {
        sort(b+1,b+n+1);
        len=unique(b+1,b+n+1)-b-1;
        for (int i=1;i<=n;i++)
        {
            a[i]=lower_bound(b+1,b+len+1,a[i])-b;
            kr[a[i]]=i;
        }
    }
    void dfs(int x,int fath)
    {
        w[x]=mx[x]=++cnt;fw[cnt]=x;
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v!=fath)
            {
                dfs(v,x);
                mx[x]=max(mx[x],mx[v]);
            }
        }
    }
    void build(int &now,int left,int right)
    {
        now=++tot;sum[now]=0;
        if (left==right) return;
        int mid=(left+right)>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
        return; 
    }
    void modify(int last,int &now,int left,int right,int pos)
    {
        now=++tot;
        ls[now]=ls[last];rs[now]=rs[last];sum[now]=sum[last]+1;
        if (left==right) return;
        int mid=(left+right)>>1;
        if (pos<=mid) modify(ls[last],ls[now],left,mid,pos);
        else modify(rs[last],rs[now],mid+1,right,pos);
    }
    int ask(int last,int now,int left,int right,int x)
    {
        if (left==right) return left;
        int mid=(left+right)>>1;
        int r=sum[ls[now]]-sum[ls[last]];
        if (x<=r) return ask(ls[last],ls[now],left,mid,x);
        else return ask(rs[last],rs[now],mid+1,right,x-r);
    }
    int main()
    {
        memset(g,0,sizeof(g));
        scanf("%d",&n);
        for (int i=1;i<=n;i++)    
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        for (int i=1;i<=n-1;i++)
        {
            scanf("%d%d",&x,&y);
            addedge(x,y);
            addedge(y,x);
        }
        divide();
        dfs(1,1);
        build(root[0],1,len);
        scanf("%d",&q);
        for (int i=1;i<=n;i++)
            modify(root[i-1],root[i],1,len,a[fw[i]]);
        for (int i=1;i<=q;i++)
        {
            scanf("%d%d",&x,&y);
            printf("%d
    ",kr[ask(root[w[x]-1],root[mx[x]],1,len,y)]);
        }
        return 0;
    }
  • 相关阅读:
    Android 编程下 Eclipse 恢复被删除的文件
    Android 编程下背景图片适配工具类
    Android 编程下 Managing Your App's Memory
    Android 编程下代码之(QQ消息列表滑动删除)
    Android 编程下 Canvas and Drawables
    Android 编程下 AlarmManager
    Android 编程下去除 ListView 上下边界蓝色或黄色阴影
    Java 编程下字符串的 16 位、32位 MD5 加密
    C#枚举类型和int类型相互转换
    MVC和普通三层架构的区别
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5716364.html
Copyright © 2011-2022 走看看