CF893F:Subtree Minimum Query(线段树合并)
Description
给你一颗有根树,点有权值,m次询问,每次问你某个点的子树中距离其不超过k的点的权值的最小值。(边权均为1,点权有可能重复,k值每次询问有可能不同,强制在线)
Input
第一行两个数,为点数$n$和树根$r$。
第二行$n$个数,为每个点的权值。
后面$n-1$行给出树边
再一行$m$,后面给出$m$组询问。
Output
一行答案。
Sample Input
5 2
1 3 2 3 5
2 3
5 1
3 4
4 1
2
1 2
2 3
Sample Output
2
5
Solution
线段树合并板子题。注意数组大小QAQ我老是开小$RE$……
感觉$Slr$和$beretty$两个人数据结构学傻了用了另一个题非常麻烦的做法写的这个题……
Code
1 #include<iostream> 2 #include<cstdio> 3 #define N (100009) 4 using namespace std; 5 6 struct Sgt{int ls,rs,min;}Segt[N<<6]; 7 struct Edge{int to,next;}edge[N<<1]; 8 int n,m,sgt_num,ans,lastans,u,v,p,q,r; 9 int a[N],Root[N],Depth[N]; 10 int head[N],num_edge; 11 12 void add(int u,int v) 13 { 14 edge[++num_edge].to=v; 15 edge[num_edge].next=head[u]; 16 head[u]=num_edge; 17 } 18 19 void Update(int &now,int l,int r,int x,int v) 20 { 21 if (!now) now=++sgt_num; 22 Segt[now].min=2e9; 23 if (l==r) {Segt[now].min=v; return;} 24 int mid=(l+r)>>1; 25 if (x<=mid) Update(Segt[now].ls,l,mid,x,v); 26 else Update(Segt[now].rs,mid+1,r,x,v); 27 int ls=Segt[now].ls, rs=Segt[now].rs; 28 Segt[now].min=min(Segt[ls].min,Segt[rs].min); 29 } 30 31 int Merge(int x,int y) 32 { 33 if (!x || !y) return x|y; 34 int tmp=++sgt_num; 35 Segt[tmp].ls=Merge(Segt[x].ls,Segt[y].ls); 36 Segt[tmp].rs=Merge(Segt[x].rs,Segt[y].rs); 37 Segt[tmp].min=min(Segt[x].min,Segt[y].min); 38 return tmp; 39 } 40 41 void DFS(int x,int fa) 42 { 43 Depth[x]=Depth[fa]+1; 44 Update(Root[x],1,n,Depth[x],a[x]); 45 for (int i=head[x]; i; i=edge[i].next) 46 if (edge[i].to!=fa) 47 { 48 DFS(edge[i].to,x); 49 Root[x]=Merge(Root[x],Root[edge[i].to]); 50 } 51 } 52 53 int Query(int now,int l,int r,int l1,int r1) 54 { 55 if (l>r1 || r<l1) return 2e9; 56 if (l1<=l && r<=r1) return Segt[now].min; 57 int mid=(l+r)>>1, ls=Segt[now].ls, rs=Segt[now].rs; 58 return min(Query(ls,l,mid,l1,r1),Query(rs,mid+1,r,l1,r1)); 59 } 60 61 int main() 62 { 63 Segt[0].min=2e9; 64 scanf("%d%d",&n,&r); 65 for (int i=1; i<=n; ++i) 66 scanf("%d",&a[i]); 67 for (int i=1; i<=n-1; ++i) 68 { 69 scanf("%d%d",&u,&v); 70 add(u,v); add(v,u); 71 } 72 DFS(r,0); 73 scanf("%d",&m); 74 for (int i=1; i<=m; ++i) 75 { 76 scanf("%d%d",&p,&q); 77 p=(p+lastans)%n+1; q=(q+lastans)%n; 78 ans=Query(Root[p],1,n,Depth[p],Depth[p]+q); 79 printf("%d\n",ans); lastans=ans; 80 } 81 }