1803: Spoj1487 Query on a tree III
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 510 Solved: 221
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
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
解题思路:主席树模板+dfs序。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
struct ss
{
int zhi,q;
}a[200011];
int len,tail=0,cnt=0,opp=0,n;
int to[210000],next[210000],h[210000];
int qg[210000],st[200011],en[200011];
int cow[200100],dui[200100],b[200100];
int sum[4010000],lx[4010000],rx[4010000];
inline int read()
{
char y; int x=0,f=1; y=getchar();
while (y<'0' || y>'9') {if (y=='-')f=-1; y=getchar();}
while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}
return x*f;
}
bool cmp(ss x,ss y)
{
return x.zhi<y.zhi;
}
void insert(int x,int y)
{
++len; to[len]=y; next[len]=h[x]; h[x]=len;
}
void dfs(int now,int f)
{
++tail; qg[tail]=now; st[now]=tail;
int u=h[now];
while (u!=0)
{
if (to[u]!=f)
{
dfs(to[u],now);
}
u=next[u];
}
++tail; qg[tail]=now; en[now]=tail;
}
void updata(int l,int r,int x,int &y,int og)
{
y=++opp; sum[y]=sum[x]+1;
if (l==r)return;
int mid=(l+r)/2;
if (og<=mid)
{
rx[y]=rx[x];
updata(l,mid,lx[x],lx[y],og);
}else
{
lx[y]=lx[x];
updata(mid+1,r,rx[x],rx[y],og);
}
}
void query(int l,int r,int x,int y,int sug)
{
if (l==r)
{
printf("%d\n",cow[l]);
return;
}
int mid=(l+r)/2;
if (sum[lx[y]]-sum[lx[x]]<sug)
{
query(mid+1,r,rx[x],rx[y],sug-(sum[lx[y]]-sum[lx[x]]));
}else
{
query(l,mid,lx[x],lx[y],sug);
}
}
int main()
{
n=read();
for (int i=1;i<=n;++i)
{
a[i].zhi=read(); a[i].q=i;
}
cnt=0;
sort(a+1,a+n+1,cmp);
for (int i=1;i<=n;++i)
{
++cnt; b[a[i].q]=cnt;
cow[cnt]=a[i].q;
}
for (int i=1;i<=n-1;++i)
{
int u,v; u=read(); v=read(); insert(u,v); insert(v,u);
}
tail=0;
dfs(1,0);
int q=read();
opp=0;
for (int i=1;i<=tail;++i)
{
updata(1,cnt,dui[i-1],dui[i],b[qg[i]]);
}
for (int i=1;i<=q;++i)
{
int x,k;
x=read(); k=read()*2;
query(1,cnt,dui[st[x]-1],dui[en[x]],k);
}
}