SPOJ QTree3 [伪的][主席树]

2 篇文章 0 订阅
2 篇文章 0 订阅

这道题并不是真正的QTree,真正的QTree系列中QTree3为query on a tree again!


1803: Spoj1487 Query on a tree III

Time Limit: 1 Sec   Memory Limit: 64 MB
Submit: 579   Solved: 260
[ Submit][ Status][ Discuss]

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.

Sample Input


5

1 3 5 2 7

1 2

2 3

1 4

3 5

4

2 3

4 1

3 2

3 2



Sample Output




5

4

5

5









HINT




Amber的play with tree系列的题….

Source


[ Submit][ Status][ Discuss]



dfs序+主席树裸题

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define N 100005
#define logN 30
#define mid ((l+r)>>1)
int n,m,x,y,k,ans,a[N],b[N],mp[N],tot,head[N],in[N],out[N];
int cnt,ls[N*logN],rs[N*logN],root[N],sz,dfn[N],sum[N*logN];
struct data{
    int next,to;
}E[N<<1];
inline int binary_search(int x){
    int l=1,r=n,ret;
    while(l<=r)
        if(b[mid]<=x)ret=mid,l=mid+1;
        else r=mid-1;
    return ret;
}
inline void addedge(int x,int y){
    E[++tot].next=head[x],head[x]=tot,E[tot].to=y;
    E[++tot].next=head[y],head[y]=tot,E[tot].to=x;
}
inline void dfs(int x,int fa){
    dfn[in[x]=++cnt]=x;
    for(register int i=head[x];i;i=E[i].next)
        if(E[i].to!=fa)dfs(E[i].to,x);
    out[x]=cnt;
}
inline void update(int &rt,int l,int r,int w){
    sum[++sz]=sum[rt]+1,ls[sz]=ls[rt],rs[sz]=rs[rt],rt=sz;
    if(l==r)return;
    if(w<=mid)update(ls[rt],l,mid,w);
    else update(rs[rt],mid+1,r,w);
}
inline int query(int l,int r,int rl,int rr,int k){
    if(l==r)return l;
    int t=sum[ls[rr]]-sum[ls[rl]];
    if(t>=k)return query(l,mid,ls[rl],ls[rr],k);
    else query(mid+1,r,rs[rl],rs[rr],k-t);
}
inline void read(int &res){
    static char ch;int flag=1;
    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
int main(){
    read(n);
    for(register int i=1;i<=n;++i)
        read(a[i]),b[i]=a[i];
    sort(b+1,b+n+1);
    for(register int i=1;i<=n;++i)
        x=binary_search(a[i]),mp[x]=i,a[i]=x;
    for(register int i=1;i<n;++i)
        read(x),read(y),addedge(x,y);
    dfs(1,0);
    for(register int i=1;i<=n;++i)
        update(root[i]=root[i-1],1,n,a[dfn[i]]);
    read(m);
    for (register int i=1;i<=m;++i){
        read(x),read(k);
        int l=in[x],r=out[x];
        ans=mp[query(1,n,root[l-1],root[r],k)];
        printf("%d\n",ans);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值