[CF893F]Subtree Minimum Query
题目大意:
给你一颗有根树,点有权值,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 }