P2590 [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个整数a和b,表示节点a和节点b之间有一条边相连。

接下来一行n个整数,第i个整数wi表示节点i的权值。

接下来1行,为一个整数q,表示操作的总数。

接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。

输出格式:

对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

输入输出样例

输入样例#1: 复制

  1. 4
  2. 1 2
  3. 2 3
  4. 4 1
  5. 4 2 1 3
  6. 12
  7. QMAX 3 4
  8. QMAX 3 3
  9. QMAX 3 2
  10. QMAX 2 3
  11. QSUM 3 4
  12. QSUM 2 1
  13. CHANGE 1 5
  14. QMAX 3 4
  15. CHANGE 3 6
  16. QMAX 3 4
  17. QMAX 2 4
  18. QSUM 3 4
输出样例#1: 复制

  1. 4
  2. 1
  3. 2
  4. 2
  5. 10
  6. 6
  7. 5
  8. 6
  9. 5
  10. 16

说明

对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

code

树链剖分1000ms左右,动态树4000ms多,不过动态树比树链剖分好写一点。

树链剖分

  1. #include<cstdio>
  2. #include<algorithm>
  3.  
  4. using namespace std;
  5.  
  6. const int N = ;
  7.  
  8. int val[N],fa[N],ch[N][],rev[N],sum[N],mx[N],st[N],top;
  9. struct Edge{
  10. int to,nxt;
  11. }e[N<<];
  12. int head[N],tot;
  13.  
  14. inline void add_edge(int u,int v) {
  15. e[++tot].to = v,e[tot].nxt = head[u],head[u] = tot;
  16. }
  17. void pushup(int x) {
  18. sum[x] = sum[ch[x][]] + sum[ch[x][]] + val[x];
  19. mx[x] = max(max(mx[ch[x][]],mx[ch[x][]]),val[x]);
  20. }
  21. void pushdown(int x) {
  22. int l = ch[x][],r = ch[x][];
  23. if (rev[x]) {
  24. rev[l] ^= ;rev[r] ^= ;
  25. swap(ch[x][],ch[x][]);
  26. rev[x] ^= ;
  27. }
  28. }
  29. bool isroot(int x) {
  30. return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;
  31. }
  32. int son(int x) {
  33. return ch[fa[x]][]==x;
  34. }
  35. void rotate(int x) {
  36. int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
  37. if (!isroot(y)) ch[z][c] = x;fa[x] = z;
  38. ch[x][!b] = y;fa[y] = x;
  39. ch[y][b] = a;if (a) fa[a] = y;
  40. pushup(y);pushup(x);
  41. }
  42. void splay(int x) {
  43. top = ;st[++top] = x;
  44. for (int i=x; !isroot(i); i=fa[i]) st[++top] = fa[i];
  45. while (top) pushdown(st[top--]);
  46. while (!isroot(x)) {
  47. int y = fa[x];
  48. if (!isroot(y)) {
  49. if (son(x)==son(y)) rotate(y);
  50. else rotate(x);
  51. }
  52. rotate(x);
  53. }
  54. }
  55. void access(int x) {
  56. for (int t=; x; t=x,x=fa[x]) {
  57. splay(x);ch[x][] = t;pushup(x);
  58. }
  59. }
  60. void makeroot(int x) {
  61. access(x);
  62. splay(x);
  63. rev[x] ^= ;
  64. }
  65. void update(int x,int y) {
  66. makeroot(x);val[x] = y;pushup(x);
  67. }
  68. int query_max(int x,int y) {
  69. makeroot(x);access(y);splay(y);
  70. return mx[y]; // -
  71. }
  72. int query_sum(int x,int y) {
  73. makeroot(x);access(y);splay(y);
  74. return sum[y]; // -
  75. }
  76. void dfs(int u) {
  77. for (int i=head[u]; i; i=e[i].nxt) {
  78. int v = e[i].to;
  79. if (v==fa[u]) continue;
  80. fa[v] = u;
  81. dfs(v);
  82. }
  83. }
  84. int main() {
  85. int n,q,x,y;
  86. char opt[];
  87. mx[] = -1e9; // -
  88. scanf("%d",&n);
  89. for (int a,b,i=; i<n; ++i) {
  90. scanf("%d%d",&a,&b);
  91. add_edge(a,b);add_edge(b,a);
  92. }
  93. for (int i=; i<=n; ++i) scanf("%d",&val[i]);
  94. dfs();
  95. scanf("%d",&q);
  96. while (q--) {
  97. scanf("%s%d%d",opt,&x,&y);
  98. if (opt[]=='H') update(x,y);
  99. else if (opt[]=='M') printf("%d\n",query_max(x,y));
  100. else printf("%d\n",query_sum(x,y));
  101. }
  102. return ;
  103. }

P2590 [ZJOI2008]树的统计(LCT)的更多相关文章

  1. P2590 [ZJOI2008]树的统计(树链剖分)

    P2590 [ZJOI2008]树的统计 虽然是入门树剖模板 但是我终于1A了(大哭) 懒得写啥了(逃 #include<iostream> #include<cstdio> ...

  2. 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)

    P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...

  3. Luogu P2590 [ZJOI2008]树的统计

    最近在学树剖,看到了这题就做了 [ZJOI2008]树的统计 思路 从题面可以知道,这题是树剖题(要求的和模板没什么区别呀喂 就是在普通的树剖上加了一个最大值 所以可以知道就是树剖+特殊的线段树 线段 ...

  4. 洛谷P2590 [ZJOI2008] 树的统计 [树链剖分]

    题目传送门 树的统计 题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t ...

  5. 【luogu P2590 [ZJOI2008]树的统计】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2590 我想学树剖QAQ #include <cstdio> #include <cstri ...

  6. 洛谷P2590 [ZJOI2008]树的统计 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2590 树链剖分模板题. 剖分过程要用到如下7个值: fa[u]:u的父节点编号: dep[u]:u的深度: size[u]: ...

  7. 洛谷 P2590 [ZJOI2008]树的统计(树链剖分)

    题目描述一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v ...

  8. 洛谷 P2590 [ZJOI2008]树的统计

    大家好,我非常喜欢暴力数据结构,于是我用块状树过了这道题目 题目: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE ...

  9. P2590 [ZJOI2008]树的统计

    题目描述 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w. 我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u ...

随机推荐

  1. GITHUB中GIT BASH基础命令行

    PS:转自https://www.cnblogs.com/WangXinPeng/p/8016293.html 1.常用命令行工具: ①cmd     ②powershell      ③git ba ...

  2. [荐]推荐一个shell学习的网站

    最近再用shell脚本,发现一个脚本学习的网站,非常好用,特此推荐一下. shell学习网站链接:http://c.biancheng.net/cpp/shell/

  3. OSS基本概念介绍

    存储空间(Bucket): 存储空间是用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间. 可以设置和修改存储空间属性用来控制地域.访问权限.生命周期等,这些属性设置直接作用于该存 ...

  4. Neo4j-3.0.3 (Debian 8)

    平台: Ubuntu 类型: 虚拟机镜像 软件包: neo4j-3.0.3 basic software database graph database infrastructure neo4j op ...

  5. python使用浮点类型float计算后,数值不对_20180827

    在练习时,输入如下代码: 结果不准确. 原因:https://blog.csdn.net/bitcarmanlee/article/details/51179572 浮点数一个普遍的问题就是在计算机的 ...

  6. 爬虫基础-http请求的基础知识

    百度百科上这么介绍爬虫: 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本. 在开发爬虫时常用的工具:ch ...

  7. wordpress中一些喜欢的主题

    Personal lite Bhari Blogi

  8. 在 Windows下用 Visual Studio 编译 OpenSSL 1.1.0

    到OpenSSL官方网站下载OpenSSL源代码包 1.下载 openssl-1.1.0.tar.gz 2.安装 ActivePerl, 可以到http://www.activestate.com/a ...

  9. StackOverflow之旅<2>------{HashMap和Hashtable的区别}

    问题 在Java中HashMap和Hashtable的区别? 哪一个对于多线程应用程序更好? 回答 Hashtable是同步的,加了synchronized锁,而HashMap不是.没有加synchr ...

  10. Wired Memory

    https://developer.apple.com/library/content/documentation/Performance/Conceptual/ManagingMemory/Arti ...