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\) 的所有点权 ...
随机推荐
- OpenCV LIBTIFF_4.0 link errors
以前用Caffe用的好好的,今天重装后居然报了很多这样的错误 /usr/lib/libopencv_highgui.so.' 1> /usr/lib/libopencv_highgui.so.' ...
- JS设计模式——12.装饰者模式
装饰者模式概述 本章讨论的是一种为对象添加特性的技术,她并不使用创建新子类这种手段. 装饰者模式可以用来透明的把对象包装在具有同样接口的另一个对象中.这样一来,就可以给一个方法添加一些行为,然后将方法 ...
- UNIX网络编程 第8章 基本UDP套接字编程
UDP是无连接的,不需要accept,TCP通过accept API来接受连接,并且将连接客户端的信息写入到accept将返回的新socket中,该新socket中有服务端和客户端的IP地址和端口,因 ...
- mipi 调试经验【转】
转自:http://blog.csdn.net/g_salamander/article/details/9163455 版权声明:本文为博主原创文章,未经博主允许不得转载. 以下是最近几个月在调试 ...
- 【Educational Codeforces Round28】
咸鱼选手发现自己很久不做cf了,晚节不保. A.Curriculum Vitae 枚举一下间断点的位置. #include<bits/stdc++.h> using namespace s ...
- POJ 3376 Finding Palindromes(manacher求前后缀回文串+trie)
题目链接:http://poj.org/problem?id=3376 题目大意:给你n个字符串,这n个字符串可以两两组合形成n*n个字符串,求这些字符串中有几个是回文串. 解题思路:思路参考了这里: ...
- SQL SERVER2008 存储过程、表、视图、函数的权限
EXEC sp_addrolemember N'db_owner', N'db'----将db 设置为 db_owner 角色中的一员 EXEC sp_droprolemember N'db_owne ...
- python 常用的标准库及第三方库
标准库Python拥有一个强大的标准库.Python语言的核心只包含数字.字符串.列表.字典.文件等常见类型和函数,而由Python标准库提供了系统管理.网络通信.文本处理.数据库接口.图形系统.XM ...
- Spring MVC之JSON数据交互和RESTful的支持
1.JSON概述 1.1 什么是JSON JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式.它是基于JavaScript的一个子集,使用了C.C ...
- Pg168-1
1.Pg168-1 package org.hanqi.pn0120; public class Computer { private double neicundx=10; public doubl ...