BZOJ3306 树

话说出题人你们能不能有点新意。。。都叫tree / 树真的大丈?!

题解:Orz 千古神犇ZYF!

  1 /**************************************************************
  2     Problem: 3306
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:1644 ms
  7     Memory:22996 kb
  8 ****************************************************************/
  9
 10 #include <cstdio>
 11 #include <algorithm>
 12
 13 using namespace std;
 14 const int N = 100005;
 15 const int M = 400005;
 16 const int inf = 1e9;
 17
 18 struct edge {
 19     int next, to;
 20     edge() {}
 21     edge(int _n, int _t) : next(_n), to(_t) {}
 22 } e[N];
 23
 24 int cnt_edge, first[N];
 25
 26 struct tree_node {
 27     int v, dep, st, ed, fa[17];
 28 } tr[N];
 29
 30 struct seg_node {
 31     seg_node *lson, *rson;
 32     int l, r, mn;
 33 } *seg_rt, mempool[M], *cnt_seg = mempool;
 34
 35 int n, root;
 36 int q[N], cnt_seq;
 37
 38 inline int read() {
 39     int x = 0, sgn = 1;
 40     char ch = getchar();
 41     while (ch < ‘0‘ || ‘9‘ < ch) {
 42         if (ch == ‘-‘) sgn = -1;
 43         ch = getchar();
 44     }
 45     while (‘0‘ <= ch && ch <= ‘9‘) {
 46         x = x * 10 + ch - ‘0‘;
 47         ch = getchar();
 48     }
 49     return sgn * x;
 50 }
 51
 52 inline void add_edge(int x, int y) {
 53     e[++cnt_edge] = edge(first[x], y);
 54     first[x] = cnt_edge;
 55 }
 56
 57 void dfs(int p) {
 58     int x;
 59     q[tr[p].st = ++cnt_seq] = p;
 60     for (x = 1; x <= 16; ++x)
 61         tr[p].fa[x] = tr[tr[p].fa[x - 1]].fa[x - 1];
 62     for (x = first[p]; x; x = e[x].next) {
 63         tr[e[x].to].dep = tr[p].dep + 1;
 64         dfs(e[x].to);
 65     }
 66     tr[p].ed = cnt_seq;
 67 }
 68
 69 #define Lson p -> lson
 70 #define Rson p -> rson
 71 #define Mn p -> mn
 72 #define L p -> l
 73 #define R p -> r
 74 #define mid (L + R >> 1)
 75 inline void seg_update(seg_node *p) {
 76     Mn = min(Lson -> mn, Rson -> mn);
 77 }
 78
 79 void seg_build(seg_node *&p, int l, int r) {
 80     p = ++cnt_seg, L = l, R = r;
 81     if (l == r) {
 82         Mn = tr[q[l]].v;
 83         return;
 84     }
 85     seg_build(Lson, l, mid), seg_build(Rson, mid + 1, r);
 86     seg_update(p);
 87 }
 88
 89 void seg_modify(seg_node *p, int pos, int v) {
 90     if (L == R) {
 91         Mn = v;
 92         return;
 93     }
 94     if (pos <= mid) seg_modify(Lson, pos, v);
 95     else seg_modify(Rson, pos, v);
 96     seg_update(p);
 97 }
 98
 99 int seg_query(seg_node *p, int l, int r) {
100     if (l > r) return inf;
101     if (L == l && r == R) return Mn;
102     if (r <= mid) return seg_query(Lson, l, r);
103     else if (mid < l) return seg_query(Rson, l, r);
104     else return min(seg_query(Lson, l, mid), seg_query(Rson, mid + 1, r));
105 }
106
107 int main() {
108     int i, Q, now, x, v;
109     char st[10];
110     n = read(), Q = read();
111     for (i = 1; i <= n; ++i) {
112         tr[i].fa[0] = read(), tr[i].v = read();
113         if (tr[i].fa[0]) add_edge(tr[i].fa[0], i);
114     }
115     tr[root = 1].dep = 1;
116     dfs(1);
117     seg_build(seg_rt, 1, n);
118     while (Q--) {
119         scanf("%s", st + 1), x = read();
120         if (st[1] == ‘V‘)
121             seg_modify(seg_rt, tr[x].st, read());
122         else if (st[1] == ‘E‘) root = x;
123         else {
124             if (root == x) printf("%d\n", seg_rt -> mn); else
125             if (tr[x].st <= tr[root].st && tr[root].ed <= tr[x].ed) {
126                 for (i = 16, now = root; ~i; --i)
127                     if (tr[tr[now].fa[i]].dep > tr[x].dep) now = tr[now].fa[i];
128                 printf("%d\n", min(seg_query(seg_rt, 1, tr[now].st - 1), seg_query(seg_rt, tr[now].ed + 1, n)));
129             } else
130             printf("%d\n", seg_query(seg_rt, tr[x].st, tr[x].ed));
131         }
132     }
133     return 0;
134 }

时间: 2024-08-28 13:46:54

BZOJ3306 树的相关文章

【BZOJ-3306】树 线段树 + DFS序

3306: 树 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 792  Solved: 262[Submit][Status][Discuss] Description 给定一棵大小为 n 的有根点权树,支持以下操作: • 换根 • 修改点权      • 查询子树最小值 Input 第一行两个整数 n, Q ,分别表示树的大小和操作数. 接下来n行,每行两个整数f,v,第i+1行的两个数表示点i的父亲和点i的权.保证f < i.如 果f = 0

[bzoj5379]Tree_dfs序_线段树_倍增lca

Tree bzoj-5379 题目大意:给定一棵$n$节点的树.支持:换根.把节点$u$和$v$的$lca$的子树加.询问$u$的子树和. 注释:$1\le n,q\le 3\times 10^5$. 想法: 和bzoj3306比较像. 发现麻烦的就是第二个操作,其实就是一个大特判而已. 小结:略. 原文地址:https://www.cnblogs.com/ShuraK/p/10199570.html

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

【树4】二叉树的遍历

简介 遍历二叉树就是按照某种顺序,将树中的结点都枚举一遍,且每个结点仅仅访问一次.因为树不是线性的结构,遍历不像线性表那样简单,因此他的遍历需要特点的算法来完成. 从某种角度讲,对二叉树的遍历就是将树形结构转换为线性结构的操作. 二叉树的遍历方法主要有如下几种: 先序遍历:先访问root结点,再先序遍历左子树,再先序遍历右子树. 中序遍历:先中序遍历左子树,再访问root结点,再中序遍历右子树. 后序遍历:先后序遍历左子树,再后序遍历右子树,再访问root结点. 层遍历:从上到下,从左到右,一层

关于左偏树的一些东东

大概所有的预备知识这里都有https://baike.baidu.com/item/%E5%B7%A6%E5%81%8F%E6%A0%91/2181887?fr=aladdin 例题1:洛谷 P3377 [模板]左偏树(可并堆) 383通过 1.2K提交 题目提供者HansBug 站长团 标签 难度提高+/省选- 时空限制1s / 128MB 提交 讨论 题解 最新讨论更多讨论 加了路径压缩就WA,路过dal… 左偏树用指针写会MLE吗..… m,n写反了也可以过,数据有… 哪位大神有pbds库

ZJOI 2008 树的统计

ZJOI2008 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身 输入输出格式 输入格式: 输入文件的第一行为一个整数n,表示节点的个数. 接下来n – 1行,每行2个整数

luoguP2590 [ZJOI2008]树的统计 [树链剖分] [TLE的LCT]

题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身 输入输出格式 输入格式: 输入文件的第一行为一个整数n,表示节点的个数. 接下来n – 1行,每行2个整数a和b,表示节点a和节点b之

(POJ 3067) Japan (慢慢熟悉的树状数组)

Japan Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29295   Accepted: 7902 Description Japan plans to welcome the ACM ICPC World Finals and a lot of roads must be built for the venue. Japan is tall island with N cities on the East coas