题目链接:https://cn.vjudge.net/problem/CodeForces-893F

题目大意:给你n个点,每一个点有权值,然后这n个点会构成一棵树,边权为1.然后有q次询问,每一次询问包括t1和t2。让你找出以t1为根节点的树上,距离t1不超过t2的节点,最小的点权值。

每一次的t1是(上次询问的结果+t1)%n+1,t2是(上次询问的结果+t1)。所以就必须的强制在线了。

具体思路:线段树合并,通过dfs序进行遍历,以每一个点的深度作为下标建树。一开始,每一个节点储存的是从当前节点到叶子节点的最小的值。但是题目中要求的是以当前节点为根节点的长度<=k的最小值,这个时候我们需要往上更新。这个更新过程就需要用到线段树合并了,把每一个子节点归并到他的父亲节点上,这样逐渐的往上递归就可以了,因为父亲节点要获取子节点的所有的信息。

然后顺便学习了一下线段树的动态开点,这个过程有点像主席树的创建过程,并不是一开始就吧线段树建立好,而是用到哪个点就给这个点编号。

这个题搞了一天才明白,,,感谢周恩杰的帮助([]~( ̄▽ ̄)~*)。

AC代码:

 #include<iostream>
#include<stack>
#include<cmath>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
# define ll long long
# define lson l,m,rt<<
# define rson m+,r,rt<<|
const int maxn = 2e5+;
# define inf 0x3f3f3f3f
# define ll_inf 0x3f3f3f3f3f3f3f
struct Edge{
ll to,nex;
}edge[maxn<<];
struct node{
ll val;
ll ch[];
void in(){val=ll_inf,ch[]=ch[]=;}
}q[maxn*];
ll head[maxn],num,depth[maxn],tot,n;
ll root[maxn];
ll a[maxn];
void init(ll n){
for(ll i=;i<=n;i++){
head[i]=-;
}
num=;
tot=;
}
void addedge(ll fr,ll to){
edge[num].nex=head[fr];
edge[num].to=to;
head[fr]=num++;
}
#define lch q[rt].ch[0]
#define rch q[rt].ch[1]
void up(ll rt){
q[rt].val=min(q[lch].val,q[rch].val);
}
void update(ll pos,ll val,ll l,ll r,ll &rt){
q[rt=++tot].in();
if(l==r){
q[rt].val=val;
return ;
}
ll mid=(l+r)>>;
if(pos<=mid)update(pos,val,l,mid,lch);
else update(pos,val,mid+,r,rch);
up(rt);
}
ll merge(ll u,ll v){
if(!v)return u;
if(!u)return v;
ll tmp=++tot;
q[tmp].in();
q[tmp].ch[]=merge(q[u].ch[],q[v].ch[]);
q[tmp].ch[]=merge(q[u].ch[],q[v].ch[]);
q[tmp].val=min(q[u].val,q[v].val);
return tmp;//注意这个地方返回的是tmp,而不是tot。因为这个过程tot还会增加,而这个地方需要的是原来的tot,所以返回的是tmp
}
void dfs(ll u,ll fr,ll dep){
depth[u]=dep;
update(depth[u],a[u],,n,root[u]);
for(ll i=head[u];i!=-;i=edge[i].nex){
ll to=edge[i].to;
if(to==fr)continue;
dfs(to,u,dep+);
root[u]=merge(root[u],root[to]);
}
}
ll query(ll L,ll R,ll l,ll r,ll x){
if(r<L||l>R)return ll_inf;
if(L<=l&&R>=r)return q[x].val;
ll mid=(l+r)>>;
return min(query(L,R,l,mid,q[x].ch[]),query(L,R,mid+,r,q[x].ch[]));
}
int main(){
ll m,st,ed;
scanf("%lld %lld",&n,&m);
for(ll i=;i<=n;i++){
scanf("%lld",&a[i]);
}
init(n);
for(ll i=;i<=n;i++){
scanf("%lld %lld",&st,&ed);
addedge(st,ed);
addedge(ed,st);
}
q[].in();
dfs(m,m,);
//for(int i=1;i<=n;i++){
//cout<<i<<" "<<root[i]<<endl;
//}
ll Case=,last=;
scanf("%lld",&Case);
while(Case--){
scanf("%lld %lld",&st,&ed);
st=(last+st)%n+;
ed=(last+ed)%n;
//cout<<depth[st]<<" "<<depth[st]+ed<<endl;
last=query(depth[st],depth[st]+ed,,n,root[st]);
printf("%lld\n",last);
}
return ;
}

Subtree Minimum Query CodeForces - 893F (线段树合并+线段树动态开点)的更多相关文章

  1. Codeforces 893F - Subtree Minimum Query

    893F - Subtree Minimum Query 题意 给出一棵树,每次询问 \(x\) \(k\),求以 \(x\) 为根结点的子树中的结点到结点 \(x\) 的距离小于等于 \(k\) 的 ...

  2. [cf contest 893(edu round 33)] F - Subtree Minimum Query

    [cf contest 893(edu round 33)] F - Subtree Minimum Query time limit per test 6 seconds memory limit ...

  3. CF893F Subtree Minimum Query 解题报告

    CF893F Subtree Minimum Query 输入输出格式 输入格式: The first line contains two integers \(n\) and \(r\) ( \(1 ...

  4. 2016湖南省赛 I Tree Intersection(线段树合并,树链剖分)

    2016湖南省赛 I Tree Intersection(线段树合并,树链剖分) 传送门:https://ac.nowcoder.com/acm/contest/1112/I 题意: 给你一个n个结点 ...

  5. Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query(主席树合并)

    题意 给定一棵 \(n\) 个点的带点权树,以 \(1\) 为根, \(m\) 次询问,每次询问给出两个值 \(p, k\) ,求以下值: \(p\) 的子树中距离 \(p \le k\) 的所有点权 ...

  6. 2019.01.19 codeforces893F.Subtree Minimum Query(线段树合并)

    传送门 线段树合并菜题. 题意简述:给一棵带点权的有根树,多次询问某个点ppp子树内距离ppp不超过kkk的点的点权最小值,强制在线. 思路: 当然可以用dfsdfsdfs序+主席树水过去. 然而线段 ...

  7. CF893F:Subtree Minimum Query(线段树合并)

    Description 给你一颗有根树,点有权值,m次询问,每次问你某个点的子树中距离其不超过k的点的权值的最小值.(边权均为1,点权有可能重复,k值每次询问有可能不同,强制在线) Input 第一行 ...

  8. EC Round 33 F. Subtree Minimum Query 主席树/线段树合并

    这题非常好!!! 主席树版本 很简单的题目,给一个按照指定节点的树,树上有点权,你需要回答给定节点的子树中,和其距离不超过k的节点中,权值最小的. 肯定首先一想,按照dfs序列建树,然后按照深度为下标 ...

  9. Codeforces 1276F - Asterisk Substrings(SAM+线段树合并+虚树)

    Codeforces 题面传送门 & 洛谷题面传送门 SAM hot tea %%%%%%% 首先我们显然可以将所有能够得到的字符串分成六类:\(\varnothing,\text{*},s, ...

随机推荐

  1. 在django中使用Redis存取session

    一.Redis的配置 1.django的缓存配置 # redis在django中的配置 CACHES = { "default": { "BACKEND": & ...

  2. Windows7安装程序无法定位现有系统分区,也无法创建新的系统分区

    解决Windows7.Windows8系统安装时“安装程序无法定位现有系统分区,也无法创建新的系统分区”提示. 方法一 把Windows7镜像发在你电脑的非系统盘的其他硬盘上. 重启机器,通过U盘启动 ...

  3. vim: 基本知识;

    1. 函数: function!   funcName(para.) content; endfunction 如果添加!,将覆盖已存在的重名函数: 注: 该博文为扩展型: 2.调用外部命令: exe ...

  4. jmeter5.0 while controller使用总结

    while controller 配合sql使用的方式 在while控制器条件中填空,这样当里面的请求断言失败后就会跳出循环 在while控制器条件中填LAST,当里面的请求断言失败后就会跳出循环,如 ...

  5. javascript实现全选,全不选,反选

    利用input的checked属性来实现:checked值为true,表示被选择,否则反之. 效果如图: js代码: <script> var butt1 = document.getEl ...

  6. windows系统下mysql-8.0.13-winx64(zip安装)

    一.下载地址: http://mirrors.163.com/mysql/Downloads/MySQL-8.0/mysql-8.0.13-winx64.zip 二.安装: 1.解压: mysql根路 ...

  7. Java Web服务收到请求时线程的情况

    Web请求线程的状态 在开发中,突然想到了这样的一个问题, Java对每一次Web的请求,是否都会创建一条线程去进行处理呢?也就是说,当一个Class的方法同时有1000个请求访问时,线程是如何运作的 ...

  8. JDBC-C3P0

    一.依赖 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&quo ...

  9. android studio导出apk

    在android studio导出的apk分为4种,一种是未签名调试版apk,一种是未签名发行版apk,一种是已签名调试版apk,还有一种是已签名发行版apk.以下将介绍这4种apk如何导出. 一.调 ...

  10. MVC实用架构设计(三)——EF-Code First(1):Repository,UnitOfWork,DbContext

    前言 终于到EF了,实在不好意思,最近有点忙,本篇离上一篇发布已经一个多星期了,工作中的小迭代告一段落,终于有点时间来继续我们的架构设计了,在这里先对大家表示歉意. 其实这段时间我并不是把这个系列给忘 ...