BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036
树链剖分模版题,打的时候注意点就行。做这题的时候,真的傻了,单词拼错检查了一个多小时...
代码如下:
1 //树链剖分 点权修改 修改单节点 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 #include <cstdio> 6 using namespace std; 7 const int MAXN = 3e4 + 10; 8 struct data { 9 int to , next; 10 }edge[MAXN << 1]; 11 int head[MAXN] , cnt , tot; 12 int top[MAXN] , par[MAXN] , son[MAXN] , size[MAXN] , dep[MAXN]; 13 int id[MAXN] , fid[MAXN]; //id[i]表示i对应在线段树上的位置 fid[i]表示线段树位置是i的叶子 对应的节点 14 int a[MAXN]; 15 16 void init() { 17 tot = cnt = 0; 18 memset(head , -1 , sizeof(head)); 19 } 20 21 inline void add(int u , int v) { 22 edge[tot].next = head[u]; 23 edge[tot].to = v; 24 head[u] = tot++; 25 } 26 27 void dfs1(int u , int p , int d) { 28 dep[u] = d , size[u] = 1 , son[u] = u , par[u] = p; 29 for(int i = head[u] ; ~i ; i = edge[i].next) { 30 int v = edge[i].to; 31 if(v == p) 32 continue; 33 dfs1(v , u , d + 1); 34 if(size[v] >= size[son[u]] || son[u] == u) 35 son[u] = v; 36 size[u] += size[v]; 37 } 38 } 39 40 void dfs2(int u , int p , int t) { 41 top[u] = t , id[u] = ++cnt; 42 fid[cnt] = u; 43 if(son[u] != u) 44 dfs2(son[u] , u , t); 45 for(int i = head[u] ; ~i ; i = edge[i].next) { 46 int v = edge[i].to; 47 if(v == p || v == son[u]) 48 continue; 49 dfs2(v , u , v); 50 } 51 } 52 53 struct segtree { 54 int l , r; 55 int sum , Max; 56 }T[MAXN << 2]; 57 58 void build(int p , int l , int r) { 59 int mid = (l + r) >> 1; 60 T[p].l = l , T[p].r = r; 61 if(l == r) { 62 T[p].Max = T[p].sum = a[fid[l]]; // 63 return ; 64 } 65 build(p << 1 , l , mid); 66 build((p << 1)|1 , mid + 1 , r); 67 T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum; 68 T[p].Max = max(T[p << 1].Max , T[(p << 1)|1].Max); 69 } 70 71 void updata(int p , int pos , int num) { 72 int mid = (T[p].l + T[p].r) >> 1; 73 if(T[p].l == T[p].r && T[p].l == pos) { 74 T[p].sum = T[p].Max = num; 75 return ; 76 } 77 if(pos <= mid) { 78 updata(p << 1 , pos , num); 79 } 80 else { 81 updata((p << 1)|1 , pos , num); 82 } 83 T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum; 84 T[p].Max = max(T[p << 1].Max , T[(p << 1)|1].Max); 85 } 86 87 int query_sum(int p , int l , int r) { 88 int mid = (T[p].l + T[p].r) >> 1; 89 if(T[p].l == l && T[p].r == r) { 90 return T[p].sum; 91 } 92 if(r <= mid) { 93 return query_sum(p << 1 , l , r); 94 } 95 else if(l > mid) { 96 return query_sum((p << 1)|1 , l , r); 97 } 98 else { 99 return query_sum(p << 1 , l , mid) + query_sum((p << 1)|1 , mid + 1 , r); 100 } 101 } 102 103 int query_max(int p , int l , int r) { 104 int mid = (T[p].l + T[p].r) >> 1; 105 if(T[p].l == l && T[p].r == r) { 106 return T[p].Max; 107 } 108 if(r <= mid) { 109 return query_max(p << 1 , l , r); 110 } 111 else if(l > mid) { 112 return query_max((p << 1)|1 , l , r); 113 } 114 else { 115 return max(query_max(p << 1 , l , mid) , query_max((p << 1)|1 , mid + 1 , r)); 116 } 117 } 118 119 int find_max(int u , int v) { 120 int fu = top[u] , fv = top[v]; 121 int Max = -1000000000; 122 while(fu != fv) { 123 if(dep[fu] >= dep[fv]) { 124 Max = max(Max , query_max(1 , id[fu] , id[u])); 125 u = par[fu]; 126 fu = top[u]; 127 } 128 else { 129 Max = max(Max , query_max(1 , id[fv] , id[v])); 130 v = par[fv]; 131 fv = top[v]; 132 } 133 } 134 if(dep[u] >= dep[v]) { 135 return max(Max , query_max(1 , id[v] , id[u])); 136 } 137 else { 138 return max(Max , query_max(1 , id[u] , id[v])); 139 } 140 } 141 142 int find_sum(int u , int v) { 143 int fu = top[u] , fv = top[v]; 144 int sum = 0; 145 while(fu != fv) { 146 if(dep[fu] > dep[fv]) { 147 sum += query_sum(1 , id[fu] , id[u]); 148 u = par[fu]; 149 fu = top[u]; 150 } 151 else { 152 sum += query_sum(1 , id[fv] , id[v]); 153 v = par[fv]; 154 fv = top[v]; 155 } 156 } 157 if(dep[u] >= dep[v]) { 158 return (sum + query_sum(1 , id[v] , id[u])); 159 } 160 else { 161 return (sum + query_sum(1 , id[u] , id[v])); 162 } 163 } 164 165 int main() 166 { 167 int n , u , v; 168 while(~scanf("%d" , &n)) { 169 init(); 170 for(int i = 1 ; i < n ; ++i) { 171 scanf("%d %d" , &u , &v); 172 add(u , v); 173 add(v , u); 174 } 175 for(int i = 1 ; i <= n ; ++i) { 176 scanf("%d" , a + i); 177 } 178 cnt = 0; 179 dfs1(1 , 1 , 0); 180 dfs2(1 , 1 , 1); 181 build(1 , 1 , cnt); 182 int m; 183 char q[10]; 184 scanf("%d" , &m); 185 while(m--) { 186 scanf("%s%d%d" , q , &u , &v); 187 if(q[0] == 'C') { 188 updata(1 , id[u] , v); 189 } 190 else if(strcmp(q ,"QMAX") == 0) { 191 printf("%d\n" , find_max(u , v)); 192 } 193 else { 194 printf("%d\n", find_sum(u , v)); 195 } 196 } 197 } 198 return 0; 199 }
转载于:https://www.cnblogs.com/Recoder/p/5518037.html
BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)相关推荐
- bzoj1036: [ZJOI2008]树的统计Count 树链剖分
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从 ...
- bzoj1036 树的统计Count 树链剖分
板子题,注意链剖基本写法: sz[o]=1 a<=l&&r<=b op=2 码: #include<iostream> #include<cstdio&g ...
- BZOJ 1036: [ZJOI2008]树的统计Count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3427 Solved: 1429 [Submi ...
- 树链剖分(bzoj 1036: [ZJOI2008]树的统计Count)
树链剖分: 把一棵树剖分为若干条链,然后利用数据结构(树状数组,SBT,Splay,线段树等等)去维护每一条链,复杂度 为O(logn),总体复杂度O(nlog²n) 步骤: ①将树的边分成重边和轻边 ...
- [ZJOI2008][BZOJ1036] 树的统计count
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 7980 Solved: 3266 [Submi ...
- 树链剖分入门+HYSBZ - 1036树的统计Count
今天学习了树链剖分,记录一下. [题目背景] HYSBZ - 1036树的统计Count [题目分析] 题目要求求任意结点之间路径的和以及路径上最大的结点,还有可能修改.如果正常做可能会很复杂(我也不 ...
- 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)
P2590 [ZJOI2008]树的统计 I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问 ...
- 【BZOJ 1036】[ZJOI2008]树的统计Count
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 [题意] [题解] 树链剖分入门题; 每一条链维护一个线段树就好; uppest ...
- BZOJ 1036 [ZJOI2008]树的统计Count
以前动态树写过这个题,今天尝试树链剖分解决~ 模板题,就声明一点,线段树维护的是点权 View Code 1 #include <iostream> 2 #include <cstd ...
- 树链剖分 - BZOJ 1036: [ZJOI2008]树的统计Count
这是树链剖分的入门题,也是我学树链剖分的第一题. 树链剖分:就是把树中和线段树联系起来,求(u,v)路径中权值的最大值和其路径的权值和. 入门blog:http://blog.sina.com.cn/ ...
最新文章
- 第十六届全国大学生智能车安徽赛区承办学校参赛队伍
- StratifiedShuffleSplit 交叉验证
- ArcGIS 10.2 三维分析工具箱部分工具不能用
- vim 的substitute
- Altium designer中元器件库(SCHLIB)元件引脚上文字(标号)大小及距离边缘位置设置
- vs2017c语言单元测试,vs2017单元测试没反应,检测出错误,有关详细信息,请查看“测试输出”窗口...
- php开源问答_PHP基础知识能力问答
- 小米air耳机重新配对_横比小米 Air 2s 和 OPPO Enco W31:同一颗芯玩出的大不同
- 性能测试工具_K6性能测试工具的使用入门
- 8月30日学习内容整理:命名空间,作用域,函数名本质,闭包
- 如何解决SQL挂起问题
- 实例88:构建InfoGAN生成MNIST模拟数据
- 单片机学习方法总结资料分享
- tkinter让用户选择文件并返回可读取文件绝对地址
- 计算机键盘字母排列依据,键盘上的26个字母排序有什么规律吗?是怎么定的?...
- C# NPOI 导出Excel 小数位数控制
- 劫持ZwQuerySystemInformation函数实现进程隐藏
- 计算机系优秀团员事迹,【国奖风采,榜样力量】真诚,感恩——计算机学院罗惠娴...
- 2022年武汉市高新技术企业各区县申报条件补贴、高企迁移奖励补助20万
- 探探自动右划,自动点击,自动加星
热门文章
- 卡巴斯基安全浏览器_知名安全软件耍流氓!擅自监控用户,双十一绝不应该成为流氓软件的狂欢!...
- 【POJ2352】Stars(树状数组模版题)
- 自建服务器选择标准,自建CDN如何选择服务器
- 数组的数据查找c语言,【查找数组面试题】面试问题:c语言实现数据… - 看准网...
- 如何测试java定时器_Java--定时器测试程序
- mysql initialsize,单机数据库优化
- 542. 01 矩阵
- 使用数组初始化vector对象
- JavaWeb:tomcat知识以及遇到的一些小问题
- rmi 反序列化漏洞_Java反序列化漏洞自动挖掘方法