题意

给定一棵 \(n\) 个点的带点权树,以 \(1\) 为根, \(m\) 次询问,每次询问给出两个值 \(p, k\) ,求以下值:

\(p\) 的子树中距离 \(p \le k\) 的所有点权最小值,询问强制在线。

\(n \le 10^5 , m \le 10^6, TL = 6s\)

题解

如果不强制在线,直接线段树合并就做完了。

强制在线,不难想到用一些可持久化的结构来维护这些东西。

其实可以类似线段树合并那样考虑,也就是说每次合并的时候我们依然使用儿子的信息。

只要在合并 \(x, y\) 共有部分的时候建出新节点,然后权值是 \(x, y\) 权值的较小值,其他的部分直接连向那些单独有的子树信息即可。

其实实现是这样的:

	int Merge(int x, int y) {
if (!x || !y) return x | y;
int o = Newnode();
ls[o] = Merge(ls[x], ls[y]);
rs[o] = Merge(rs[x], rs[y]);
minv[o] = min(minv[x], minv[y]);
return o;
}

这样的话,既可以保留子树信息,又可以得到这个节点新的信息。

最后空间复杂度就是 \(O(n \log n)\) ,时间复杂度是 \(O((n + m) \log n)\) 的。

总结

强制在线问题,用可持久化数据结构去解决就行了,也就是把平常的数据结构记历史版本,并尽量用之前的信息。

代码

#include <bits/stdc++.h>

#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define pb push_back using namespace std; template<typename T> inline bool chkmin(T &a, T b) {return b < a ? a = b, 1 : 0;}
template<typename T> inline bool chkmax(T &a, T b) {return b > a ? a = b, 1 : 0;} inline int read() {
int x(0), sgn(1); char ch(getchar());
for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);
return x * sgn;
} void File() {
#ifdef zjp_shadow
freopen ("F.in", "r", stdin);
freopen ("F.out", "w", stdout);
#endif
} const int N = 1e5 + 1e3, inf = 0x3f3f3f3f; #define lson ls[o], l, mid
#define rson rs[o], mid + 1, r template<int Maxn>
struct Chair_Man_Tree { int ls[Maxn], rs[Maxn], minv[Maxn], Size; Chair_Man_Tree() { minv[0] = inf; } inline int Newnode() {
int o = ++ Size; minv[o] = inf; return o;
} void Update(int &o, int l, int r, int up, int uv) {
if (!o) o = Newnode();
if (l == r) { chkmin(minv[o], uv); return ; }
int mid = (l + r) >> 1;
up <= mid ? Update(lson, up, uv) : Update(rson, up, uv);
minv[o] = min(minv[ls[o]], minv[rs[o]]);
} int Query(int o, int l, int r, int ql, int qr) {
if (!o) return inf;
if (ql <= l && r <= qr) return minv[o];
int mid = (l + r) >> 1;
if (qr <= mid) return Query(lson, ql, qr);
if (ql > mid) return Query(rson, ql, qr);
return min(Query(lson, ql, qr), Query(rson, ql, qr));
} int Merge(int x, int y) {
if (!x || !y) return x | y;
int o = Newnode();
ls[o] = Merge(ls[x], ls[y]);
rs[o] = Merge(rs[x], rs[y]);
minv[o] = min(minv[x], minv[y]);
return o;
} }; vector<int> G[N]; int val[N], rt[N], dep[N]; int n, S; Chair_Man_Tree<N * 80> T; void Dfs(int u, int fa = 0) {
dep[u] = dep[fa] + 1;
for (int v : G[u]) if (v != fa)
Dfs(v, u), rt[u] = T.Merge(rt[u], rt[v]);
T.Update(rt[u], 1, n, dep[u], val[u]);
} int main () { File(); n = read(); S = read(); For (i, 1, n)
val[i] = read(); For (i, 1, n - 1) {
int u = read(), v = read();
G[u].pb(v); G[v].pb(u);
} Dfs(S); int q = read(), ans = 0;
For (i, 1, q) {
int x = (read() + ans) % n + 1, k = (read() + ans) % n;
printf ("%d\n", ans = T.Query(rt[x], 1, n, dep[x], min(dep[x] + k, n)));
} return 0; }

Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query(主席树合并)的更多相关文章

  1. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...

  2. Educational Codeforces Round 71 (Rated for Div. 2)-F. Remainder Problem-技巧分块

    Educational Codeforces Round 71 (Rated for Div. 2)-F. Remainder Problem-技巧分块 [Problem Description] ​ ...

  3. [Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和)

    [Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和) E. Permuta ...

  4. Educational Codeforces Round 33 (Rated for Div. 2) E. Counting Arrays

    题目链接 题意:给你两个数x,yx,yx,y,让你构造一些长为yyy的数列,让这个数列的累乘为xxx,输出方案数. 思路:考虑对xxx进行质因数分解,设某个质因子PiP_iPi​的的幂为kkk,则这个 ...

  5. Educational Codeforces Round 33 (Rated for Div. 2) 题解

    A.每个状态只有一种后续转移,判断每次转移是否都合法即可. #include <iostream> #include <cstdio> using namespace std; ...

  6. Educational Codeforces Round 33 (Rated for Div. 2)A-F

    总的来说这套题还是很不错的,让我对主席树有了更深的了解 A:水题,模拟即可 #include<bits/stdc++.h> #define fi first #define se seco ...

  7. Educational Codeforces Round 33 (Rated for Div. 2) D. Credit Card

    D. Credit Card time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  8. Educational Codeforces Round 33 (Rated for Div. 2) C. Rumor【并查集+贪心/维护集合最小值】

    C. Rumor time limit per test 2 seconds memory limit per test 256 megabytes input standard input outp ...

  9. Educational Codeforces Round 33 (Rated for Div. 2) B. Beautiful Divisors【进制思维/打表】

    B. Beautiful Divisors time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

随机推荐

  1. Python IO模型

    这篇博客是本人借鉴一些大神的博客并结合自己的学习过程写下的. 事件驱动模型 事件驱动模型是一种编程范式,这里程序的执行流由外部事件来决定.它的特点是包含一个事件循环,当外部事件发生时,不断从队列里取出 ...

  2. redis中的hash、列表、集合操作

    一.hash操作 数据结构:key:{k1:v1, k2:v2, k3:v3} 类似Python中的字典 如:info : {name: lina, age: 22, sex: F} hset key ...

  3. Spring.profile配合Jenkins发布War包,实现开发、测试和生产环境的按需切换

    前两篇不错 Spring.profile实现开发.测试和生产环境的配置和切换 - Strugglion - 博客园https://www.cnblogs.com/strugglion/p/709102 ...

  4. 【Python3练习题 015】 一球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下。求它在第10次落地时,共经过多少米?第10次反弹多高?

    a = [100]  #每个‘反弹落地’过程经过的路程,第1次只有落地(100米) h = 100  #每个‘反弹落地’过程,反弹的高度,第1次为100米 print('第1次从%s米高落地,走过%s ...

  5. 理解ORM的前提:数据库中的范式和约束

    理解ORM的前提:数据库中的范式和约束 一.数据库中的范式: 范式, 英文名称是 Normal Form,它是英国人 E.F.Codd(关系数据库的老祖宗)在上个世纪70年代提出关系数据库模型后总结出 ...

  6. Failed to bind properties under 'spring.datasource' to javax.sql.DataSource

    这是我的配置文件 # 国际化配置文件(包名.基础名) spring.messages.basename=i18n.login server.tomcat.uri-encoding=UTF- sprin ...

  7. python爬虫之scrapy的pipeline的使用

    scrapy的pipeline是一个非常重要的模块,主要作用是将return的items写入到数据库.文件等持久化模块,下面我们就简单的了解一下pipelines的用法. 案例一: items池 cl ...

  8. centos7根分区扩容(亲测有效)

    root@haojftest:~# df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/mapper/centos_test2-root 28G 14G 15G % / devtmpfs ...

  9. PHPCMS的使用

    1.下载安装phpcms 下载完后解压将install_packages上传到服务器并重命名为phpcms_test: 更改目录文件系统权限: chmod -R 777 phpcms_test 配置n ...

  10. Armstrong公理

    从已知的一些函数依赖,可以推导出另外一些函数依赖,这就需要一系列推理规则,这些规则常被称作“Armstrong 公理”. 设U 是关系模式R 的属性集,F 是R 上成立的只涉及U 中属性的函数依赖集. ...