CF893F Subtree Minimum Query 主席树

如果是求和就很好做了...
不是求和也无伤大雅....
一维太难限制条件了,考虑二维限制
一维$dfs$序,一维$dep$序
询问$(x, k)$对应着在$dfs$上查$[dfn[x], dfn[x] + sz[x] - 1]$,在$dep$序上查$[dep[x], dep[x] + k]$
这样子,每个询问对应查询一段矩形内的最小值
然而树套树是过不了的.....
发现一个询问看似在$dep$序上对应了一段区间,实际上可以扩展到对应一段前缀
这样子,只需要一个主席树就可以做到了
复杂度$O(n \log n)$
#include <map>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
#define ri register int
#define tpr template <typename ra>
#define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
#define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)
#define gc getchar
inline int read() {
int p = , w = ; char c = gc();
while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
while(c >= '' && c <= '') p = p * + c - '', c = gc();
return p * w;
}
int wr[], rw;
#define pc(iw) putchar(iw)
tpr inline void write(ra o, char c = '\n') {
if(!o) pc('');
if(o < ) o = -o, pc('-');
while(o) wr[++ rw] = o % , o /= ;
while(rw) pc(wr[rw --] + '');
pc(c);
}
tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; }
tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; }
tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, : ; }
tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, : ; }
}
using namespace std;
using namespace remoon; #define sid 300050
#define oid 12050000 int dfn[sid], sz[sid];
int n, r, m, id, tim, cnp, mxd;
int rt[sid], nxt[sid], node[sid], cap[sid];
int fa[sid], q[sid], w[sid], dep[sid];
int ls[oid], rs[oid], miv[oid]; inline void addedge(int u, int v) {
nxt[++ cnp] = cap[u]; cap[u] = cnp; node[cnp] = v;
} #define cur node[i]
inline void dfs(int o, int f) {
fa[o] = f; dep[o] = dep[f] + ;
sz[o] = ; dfn[o] = ++ tim;
for(int i = cap[o]; i; i = nxt[i])
if(cur != f) dfs(cur, o), sz[o] += sz[cur];
} inline void insert(int &now, int pre, int l, int r, int p, int v) {
now = ++ id;
ls[now] = ls[pre]; rs[now] = rs[pre];
miv[now] = min(miv[pre], v);
if(l == r) return;
int mid = (l + r) >> ;
if(p <= mid) insert(ls[now], ls[pre], l, mid, p, v);
else insert(rs[now], rs[pre], mid + , r, p, v);
} inline void build() {
int fr = , to = ;
q[++ to] = r; miv[] = 1e9;
while(fr <= to) {
int o = q[fr];
for(ri i = cap[o]; i; i = nxt[i])
if(cur != fa[o]) q[++ to] = cur;
if(dep[o] != dep[q[fr - ]])
insert(rt[dep[o]], rt[dep[o] - ], , n, dfn[o], w[o]);
else insert(rt[dep[o]], rt[dep[o]], , n, dfn[o], w[o]);
fr ++; cmax(mxd, dep[o]);
}
} inline int qry(int o, int l, int r, int ml, int mr) {
if(ml > r || mr < l || !o) return 1e9;
if(ml <= l && mr >= r) return miv[o];
int mid = (l + r) >> ;
return min(qry(ls[o], l, mid, ml, mr), qry(rs[o], mid + , r, ml, mr));
} int main() {
n = read(); r = read();
rep(i, , n) w[i] = read();
rep(i, , n) {
int u = read(), v = read();
addedge(u, v); addedge(v, u);
}
dfs(r, ); build();
int lst = ; m = read();
rep(i, , m) {
int x = (read() + lst) % n + ;
int k = (read() + lst) % n;
write(lst = qry(rt[min(dep[x] + k, mxd)], , n, dfn[x], dfn[x] + sz[x] - ));
}
return ;
}
CF893F Subtree Minimum Query 主席树的更多相关文章
- EC Round 33 F. Subtree Minimum Query 主席树/线段树合并
这题非常好!!! 主席树版本 很简单的题目,给一个按照指定节点的树,树上有点权,你需要回答给定节点的子树中,和其距离不超过k的节点中,权值最小的. 肯定首先一想,按照dfs序列建树,然后按照深度为下标 ...
- CF893F:Subtree Minimum Query(线段树合并)
Description 给你一颗有根树,点有权值,m次询问,每次问你某个点的子树中距离其不超过k的点的权值的最小值.(边权均为1,点权有可能重复,k值每次询问有可能不同,强制在线) Input 第一行 ...
- CF893F Subtree Minimum Query 解题报告
CF893F Subtree Minimum Query 输入输出格式 输入格式: The first line contains two integers \(n\) and \(r\) ( \(1 ...
- [CF893F] Subtree Minimum Query
Description: 给定一棵树,每次询问某点子树中到其不超过k的所有点的最小点权 强制在线 Hint: \(n,m\le 10^5\) Solution: 看到题目第一反应是以深度为下标,dfs ...
- Codeforces 893F - Subtree Minimum Query
893F - Subtree Minimum Query 题意 给出一棵树,每次询问 \(x\) \(k\),求以 \(x\) 为根结点的子树中的结点到结点 \(x\) 的距离小于等于 \(k\) 的 ...
- [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 ...
- Subtree Minimum Query CodeForces - 893F (线段树合并+线段树动态开点)
题目链接:https://cn.vjudge.net/problem/CodeForces-893F 题目大意:给你n个点,每一个点有权值,然后这n个点会构成一棵树,边权为1.然后有q次询问,每一次询 ...
- 2019.01.19 codeforces893F.Subtree Minimum Query(线段树合并)
传送门 线段树合并菜题. 题意简述:给一棵带点权的有根树,多次询问某个点ppp子树内距离ppp不超过kkk的点的点权最小值,强制在线. 思路: 当然可以用dfsdfsdfs序+主席树水过去. 然而线段 ...
- Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query(主席树合并)
题意 给定一棵 \(n\) 个点的带点权树,以 \(1\) 为根, \(m\) 次询问,每次询问给出两个值 \(p, k\) ,求以下值: \(p\) 的子树中距离 \(p \le k\) 的所有点权 ...
随机推荐
- UNIX环境高级编程 第9章 进程关系
在第8章学习了进程的控制原语,通过各种进程原语可以对进程进行控制,包括新建进程.执行新程序.终止进程等.在使用fork( )产生新进程后,就出现了进程父子进程的概念,这是进程间的关系.本章更加详细地说 ...
- Python 使用 Redis 操作
1.redis简介 redis是一款开源免费的高性能key-value数据库,redis特点: 支持更多的数据类型:字符串(String).列表(List).哈希(Map).数字(Int).集合(Se ...
- mysql高可用架构 -> MHA配置binlog-server-06
前期准备 1.准备一台新的mysql实例(db03),GTID必须开启. 2.将来binlog接收目录,不能和主库binlog目录一样 停止mha masterha_stop --conf=/etc/ ...
- C# 托管资源 与 非托管资源
C# 托管资源 与 非托管资源 托管资源一般是指被CLR控制的内存资源,这些资源的管理可以由CLR来控制,.NET可以自动进行回收,主要是指托管堆上分配的内存资源.例如程序中分配的对象,作用域内的变量 ...
- go 切片的 插入、删除
package main import ( "fmt" ) func InsertSpringSliceCopy(slice, insertion []string, index ...
- 洛谷P3378堆
传送门啦 #include <iostream> #include <cstdio> #include <cstring> #include <algorit ...
- HDU 3613 Best Reward(manacher求前、后缀回文串)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3613 题目大意: 题目大意就是将字符串s分成两部分子串,若子串是回文串则需计算价值,否则价值为0,求分 ...
- Codeforces 801C Voltage Keepsake(二分枚举+浮点(模板))
题目链接:http://codeforces.com/contest/801/problem/C 题目大意:给你一些电器以及他们的功率,还有一个功率一定的充电器可以给这些电器中的任意一个充电,并且不计 ...
- (二)Jsoup 查找 DOM 元素
第一节: Jsoup 查找 DOM 元素 getElementById(String id) 根据 id 来查询 DOM getElementsByTag(String tagName) 根据 tag ...
- Shell学习笔记:<<EOF子命令
在shell编程中,“EOF”通常与“<<”结合使用,“<<EOF”表示后续的输入作为子命令或子shell的输入,直到遇到“EOF”,再次返回到主调用shell,可将其理解为分 ...