题目大意:
给你一颗有根树,点有权值,m次询问,每次问你某个点的子树中距离其不超过k的点的权值的最小值。(边权均为1,点权有可能重复,k值每次询问有可能不同,强制在线)
做法跟HDU那道题一样,开两颗线段树,一颗维护每个深度最小值,一颗维护每个值所在最低深度,合并第二个线段树的时候顺便修改第一个即可
代码:
1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<algorithm>
5 #define M 100010
6 using namespace std;
7 int n,m,num,cnt,top,r,ans;
8 int head[M],a[M],b[M],rt1[M],rt2[M],deep[M];
9 int val[M<<8],ch[M<<8][2];
10 struct point{int to,next;}e[M<<1];
11 void add(int from,int to) {
12 e[++num].next=head[from];
13 e[num].to=to;
14 head[from]=num;
15 }
16 int get(int x) {
17 int l=1,r=top;
18 while(l<=r) {
19 int mid=(l+r)/2;
20 if(b[mid]==x) return mid;
21 if(b[mid]>x) r=mid-1;
22 else l=mid+1;
23 }
24 }
25 int insert(int rt,int l,int r,int x,int v) {
26 int node=++cnt;val[node]=min(val[rt],v);
27 if(l==r) return node;
28 int mid=(l+r)/2;
29 ch[node][0]=ch[rt][0],ch[node][1]=ch[rt][1];
30 if(x<=mid) ch[node][0]=insert(ch[rt][0],l,mid,x,v);
31 else ch[node][1]=insert(ch[rt][1],mid+1,r,x,v);
32 return node;
33 }
34 int merge1(int x,int y,int l,int r) {
35 if(!x||!y) return x+y;
36 int node=++cnt,mid=(l+r)/2;
37 val[node]=min(val[x],val[y]);
38 if(l==r) return node;
39 ch[node][0]=merge1(ch[x][0],ch[y][0],l,mid);
40 ch[node][1]=merge1(ch[x][1],ch[y][1],mid+1,r);
41 return node;
42 }
43 int merge2(int x,int y,int l,int r,int id) {
44 if(!x||!y) return x+y;
45 int node=++cnt,mid=(l+r)/2;
46 if(l==r) {
47 val[node]=min(val[x],val[y]);
48 rt1[id]=insert(rt1[id],1,n,val[node],l);
49 return node;
50 }
51 ch[node][0]=merge2(ch[x][0],ch[y][0],l,mid,id);
52 ch[node][1]=merge2(ch[x][1],ch[y][1],mid+1,r,id);
53 return node;
54 }
55 int query(int node,int l,int r,int l1,int r1) {
56 if(l1<=l&&r1>=r) return val[node];
57 int mid=(l+r)/2,ans=1e9;
58 if(l1<=mid) ans=min(ans,query(ch[node][0],l,mid,l1,r1));
59 if(r1>mid) ans=min(ans,query(ch[node][1],mid+1,r,l1,r1));
60 return ans;
61 }
62 void dfs(int x,int fa) {
63 deep[x]=deep[fa]+1;
64 rt1[x]=insert(0,1,n,deep[x],a[x]);
65 rt2[x]=insert(0,1,n,a[x],deep[x]);
66 for(int i=head[x];i;i=e[i].next)
67 if(e[i].to!=fa) {
68 dfs(e[i].to,x);
69 rt1[x]=merge1(rt1[x],rt1[e[i].to],1,n);
70 rt2[x]=merge2(rt2[x],rt2[e[i].to],1,n,x);
71 }
72 }
73 int main() {
74 memset(val,1,sizeof(val));
75 scanf("%d%d",&n,&r);
76 for(int i=1;i<=n;i++)
77 scanf("%d",&a[i]),b[++top]=a[i];
78 sort(b+1,b+1+top);top=unique(b+1,b+1+top)-b-1;
79 for(int i=1;i<=n;i++) a[i]=get(a[i]);
80 for(int i=1;i<n;i++) {
81 int a,b;scanf("%d%d",&a,&b);
82 add(a,b),add(b,a);
83 }
84 dfs(r,0);scanf("%d",&m);
85 for(int i=1;i<=m;i++) {
86 int x,k;scanf("%d%d",&x,&k);
87 x=(x+ans)%n+1,k=(k+ans)%n;
88 printf("%d\n",ans=b[query(rt1[x],1,n,deep[x],min(deep[x]+k,n))]);
89 }
90 return 0;
91 }