博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF893F:Subtree Minimum Query(线段树合并)
阅读量:7056 次
发布时间:2019-06-28

本文共 2433 字,大约阅读时间需要 8 分钟。

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
2 #include
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
>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 }

转载于:https://www.cnblogs.com/refun/p/10060147.html

你可能感兴趣的文章
Citrix XenApp Lic指向设置
查看>>
移动视频技术
查看>>
U盘安装Linux系统Centos5.x中遇到的问题及解决方案
查看>>
P1063 能量项链(区间dp)
查看>>
centos6 内核优化
查看>>
Linux安装gitlab
查看>>
十四条令PHP初学者头疼问题大总结(1)
查看>>
MySQL的备份与还原
查看>>
加密U盘专业加密芯片方案
查看>>
js比较字符数组元素是否重复
查看>>
码客Online:HTC Zoe是什么功能?
查看>>
windows server 2012 r2 搭建企业文件共享存储
查看>>
我的友情链接
查看>>
[20180606]如何dump数据库里面的汉字.txt
查看>>
C#面向对象(四)虚方法实现多态
查看>>
day3-Nfs
查看>>
函数栈帧(用汇编来剖析)
查看>>
C++中const用法总结(转)
查看>>
给Windows 2003文件夹设置权限
查看>>
Android x86+ADT
查看>>