bzoj 1036: [ZJOI2008]树的统计Count (树链剖分)
ps:这道题过的人真多啊
一道树剖的模板题
(好像还可以用lct做, 然而我并不会
代码如下
/**************************************************************
Problem: 1036
User: cminus
Language: C++
Result: Accepted
Time:2380 ms
Memory:4052 kb
****************************************************************/ #include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = ;
#define ls (o << 1)
#define rs (ls + 1) int n, w[N];
int fa[N], size[N], hs[N], dep[N], top[N], pos[N], tot;
int maxn[N*], sum[N*], L, R;
vector < int > edge[N]; inline void dfs1(int u, int d, int f){
dep[u] = d; fa[u] = f; size[u] = ; hs[u] = -;
int tmp = ;
for (int i = ; i < edge[u].size(); i++){
int &v = edge[u][i];
if (v == f) continue;
dfs1(v, d + , u);
if (size[v] > tmp)
tmp = size[v], hs[u] = v;
size[u] += size[v];
}
} inline void dfs2(int u, int t){
top[u] = t, pos[u] = ++tot;
if (hs[u] == -) return ;
dfs2(hs[u], t);
for (int i = ; i < edge[u].size(); i++){
int &v = edge[u][i];
if (v != hs[u] && v != fa[u])
dfs2(v, v);
}
} inline int getSum(int o, int l, int r){
if (L <= l && r <= R) return sum[o];
int mid = (l + r) >> , ans = ;
if (L <= mid) ans += getSum(ls, l, mid);
if (R > mid) ans += getSum(rs, mid + , r);
return ans;
} inline int getMax(int o, int l, int r){
if (L <= l && r <= R) return maxn[o];
int mid = l + r >> , ans = -0x3f3f3f3f;
if (L <= mid) ans = max(ans, getMax(ls, l, mid));
if (R > mid) ans = max(ans, getMax(rs, mid + , r));
return ans;
} inline int getMax(int l, int r){
L = l, R = r;
return getMax(, , tot);
} inline int getSum(int l, int r){
L = l, R = r;
return getSum(, , tot);
} inline void queryMax(int u, int v){
int f1 = top[u], f2 = top[v], ans = -0x3f3f3f3f;
while(f1 != f2){
if (dep[f1] < dep[f2])
swap(u, v), swap(f1, f2);
ans = max(ans, getMax(pos[f1], pos[u]));
u = fa[f1]; f1 = top[u];
}
if (dep[u] > dep[v]) swap(u, v);
printf("%d\n", max(ans, getMax(pos[u], pos[v])));
} inline void querySum(int u, int v){
int f1 = top[u], f2 = top[v], ans = ;
while(f1 != f2){
if (dep[f1] < dep[f2])
swap(u, v), swap(f1, f2);
ans += getSum(pos[f1], pos[u]);
u = fa[f1]; f1 = top[u];
}
if (dep[u] > dep[v]) swap(u, v);
printf("%d\n", ans + getSum(pos[u], pos[v]));
} inline void modify(int o, int l, int r, int u, int a){
if(l == r){
sum[o] = maxn[o] = a;
return ;
}
int mid = l + r >> ;
if (u <= mid) modify(ls, l, mid, u, a);
else modify(rs, mid + , r, u, a);
sum[o] = sum[ls] + sum[rs];
maxn[o] = max(maxn[ls], maxn[rs]);
} int main(){
scanf("%d", &n);
for (int i = ; i < n; i++){
int x, y; scanf("%d %d", &x, &y);
edge[x].push_back(y);
edge[y].push_back(x);
}
for (int i = ; i <= n; i++) scanf("%d", &w[i]);
dfs1(, , -); dfs2(, );
for (int i = ; i <= n; i++)
modify(, , tot, pos[i], w[i]);
int q; scanf("%d", &q);
char str[]; int x, y;
while(q--){
scanf("%s%d%d", str, &x, &y);
if (!strcmp(str, "QMAX")) queryMax(x, y);
else if (*str == 'C') modify(, , tot, pos[x], y);
else querySum(x, y);
}
return ;
}
bzoj 1036: [ZJOI2008]树的统计Count (树链剖分)的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 11102 Solved: 4490[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- bzoj 1036: [ZJOI2008]树的统计Count 树链剖分+线段树
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 16294 Solved: 6645[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14982 Solved: 6081[Submit ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分)(线段树单点修改)
[ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14968 Solved: 6079[Submit][Stat ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...
- Cogs 1688. [ZJOI2008]树的统计Count(树链剖分+线段树||LCT)
[ZJOI2008]树的统计Count ★★★ 输入文件:bzoj_1036.in 输出文件:bzoj_1036.out 简单对比 时间限制:5 s 内存限制:162 MB [题目描述] 一棵树上有n ...
- BZOJ 1036 [ZJOI2008]树的统计Count (树链剖分 - 点权剖分 - 单点权修改)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
随机推荐
- python list comprehensions
list comprehensions 列表解释 You now have all the knowledge necessary to begin writing list comprehensio ...
- gulp常用插件之del使用
更多gulp常用插件使用请访问:gulp常用插件汇总 del这是一款删除文件的工具. 更多使用文档请点击访问del工具官网. 安装 npm install del API del(patterns, ...
- ROS开发--在订阅话题的回调函数中发布话题
处理激光数据时,需要将处理后的激光数据再发布,需要保持一致的频率,所以必须在回调函数中发布激光数据信息. 代码参考:https://blog.csdn.net/heyijia0327/article/ ...
- MySql 小表驱动大表
在了解之前要先了解对应语法 in 与 exist. IN: select * from A where A.id in (select B.id from B) in后的括号的表达式结果要求之输出一列 ...
- H5_0009:关于HTML5中Canvas的宽、高设置问题
关于HTML5中Canvas的宽.高设置问题 Canvas元素默认宽 300px, 高 150px, 设置其宽高可以使用如下方法(不会被拉伸): 方法一: <canvas widt ...
- Python之三:运算符与表达式
1.运算符: 1.1.运算符种类: 运算符 名称 说明 例子 + 加 5+4 - 减 * 乘 / 除 // 取整除 商的整数部分 3//2,结果 ...
- 获取url参数(jq 扩展包)
(function($){ $.extend({ urlGet:function(url) { var getUrl = url ? url.split("?") : window ...
- SpringMVC 和 Struts2的区别
SpringMVC 和 Struts2的区别 1.Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方 ...
- Date/Math/String对象的函数
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- MySQL主键设计盘点
目录 主键定义 主键设计和应用原则 主键生成策略 自增ID UUID 自建的id生成器 Twitter的snowflake算法 @ 最近在项目中用了UUID的方式生成主键,一开始只是想把这种UUID的 ...