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
",ans); lastans=ans;
80     }
81 }
原文地址:https://www.cnblogs.com/refun/p/10060147.html