BZOJ 1036:树的统计Count(树链剖分)
http://www.lydsy.com/JudgeOnline/problem.php?id=1036
题意:中文题意。
思路:也是普通的树链剖分。唯一注意的点是在change函数中
while(top[u] != top[v]) {
if(dep[top[u]] < dep[top[v]]) swap(u, v);
if(type == ) ans = max(ans, query(, , tim, tid[top[u]], tid[u], type));
else ans += query(, , tim, tid[top[u]], tid[u], type);
u = fa[top[u]];
}
这里的dep比较的是节点的top节点的深度,而不是直接比较节点的深度。因为这里WA了好久。只能说还未完全理解透细节。
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define N 30010
#define INF 10000000000
#define lson rt<<1, l, m
#define rson rt<<1|1, m + 1, r struct node
{
int v, nxt, w;
}edge[N*];
int top[N], tid[N], fa[N], son[N], siz[N], dep[N], rak[N], w[N], tim;
int head[N], tot;
struct T
{
long long sum;
long long ma;
}tree[N<<]; void init()
{
memset(head, -, sizeof(head));
memset(son, -, sizeof(son));
tot = tim = ;
} void add(int u, int v)
{
edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;
} void dfs1(int u, int f, int d)
{
siz[u] = ;
dep[u] = d;
fa[u] = f;
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(v == f) continue;
dfs1(v, u, d + );
siz[u] += siz[v];
if(son[u] == - || siz[son[u]] < siz[v]) son[u] = v;
}
} void dfs2(int u, int tp)
{
top[u] = tp;
tid[u] = ++tim;
rak[tim] = u;
if(son[u] == -) return ;
dfs2(son[u], tp);
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(v != fa[u] && v != son[u]) dfs2(v, v);
}
} void pushup(int rt)
{
tree[rt].sum = tree[rt<<].sum + tree[rt<<|].sum;
tree[rt].ma = max(tree[rt<<].ma, tree[rt<<|].ma);
} void build(int rt, int l, int r)
{
tree[rt].sum = ;
tree[rt].ma = ;
if(l == r) {
tree[rt].sum = w[rak[l]];
tree[rt].ma = w[rak[l]];
return ;
}
int m = (l + r) >> ;
build(lson); build(rson);
pushup(rt);
} void update(int rt, int l, int r, int id, int val)
{
if(l == r && l == id) {
tree[rt].sum = val;
tree[rt].ma = val;
return ;
}
int m = (l + r) >> ;
if(id <= m) update(lson, id, val);
else update(rson, id, val);
pushup(rt);
} long long query(int rt, int l, int r, int L, int R, int type)
{
long long ans = ;
if(type == ) ans = -INF;
if(L <= l && r <= R) {
if(type == ) ans = max(ans, tree[rt].ma);
else ans += tree[rt].sum;
return ans;
}
int m = (l + r) >> ;
if(L <= m) {
if(type == ) ans = max(ans, query(lson, L, R, type));
else ans += query(lson, L, R, type);
}
if(m < R) {
if(type == ) ans = max(ans, query(rson, L, R, type));
else ans += query(rson, L, R, type);
}
return ans;
} long long change(int u, int v, int type)
{
long long ans = ;
if(type == ) ans = -INF;
while(top[u] != top[v]) {
if(dep[top[u]] < dep[top[v]]) swap(u, v);
if(type == ) ans = max(ans, query(, , tim, tid[top[u]], tid[u], type));
else ans += query(, , tim, tid[top[u]], tid[u], type);
u = fa[top[u]];
}
if(dep[u] > dep[v]) swap(u, v);
if(type == ) ans = max(ans, query(, , tim, tid[u], tid[v], type));
else ans += query(, , tim, tid[u], tid[v], type);
return ans;
} int main()
{
int n, q;
scanf("%d", &n);
init();
for(int i = ; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
add(u, v); add(v, u);
}
for(int i = ; i <= n; i++) scanf("%d", &w[i]);
dfs1(, , );
dfs2(, );
build(, , tim);
// for(int i = 1; i <= n; i++) printf("tid[%d] : %d\n", i, tid[i]);
scanf("%d", &q);
while(q--) {
char s[];
int a, b;
scanf("%s%d%d", s, &a, &b);
if(s[] == 'C') {
update(, , tim, tid[a], b);
} else {
int type = ;
if(s[] == 'S') type = ;
printf("%lld\n", change(a, b, type));
}
}
return ;
}
BZOJ 1036:树的统计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 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
随机推荐
- .NET反射(Reflection)机制
C#编译后的文件主要由IL代码和元数据组成,元数据为.NET组件提供了丰富的自描述特性,它使得我们可以在代码运行时获知组件中的类型等重要的信息.C#中这是通过一种称作映射(Reflection)的机制 ...
- WPF 面试题及答案(二)
一 · WPF中什么是样式? 首先明白WPF中样式属于资源中重要的一种. 同时样式也是属性值的集合,能被应用到一个合适的元素中,或者说能将一组属性应用到多个元素. WPF中样式可以设置任何依赖属性. ...
- Java Thread线程控制
一.线程和进程 进程是处于运行中的程序,具有一定的独立能力,进程是系统进行资源分配和调度的一个独立单位. 进程特征: A.独立性:进程是系统中独立存在的实体,可以拥有自己独立的资源,每个进程都拥有自己 ...
- zabbix监控路由器所有接口信息
zabbix监控路由器所有接口信息 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 1.首先在服务器端安装snmp工具 [root@bogon yinzhengjie]# yum - ...
- !!20160829——多次错误的T+0操作
- 转:python字符串/元组/列表/字典互转
#-*-coding:utf-8-*- #1.字典 dict = {'name': 'Zara', 'age': 7, 'class': 'First'} #字典转为字符串,返回:<type ...
- 转:SELENIUM TIPS: CSS SELECTORS
This page will show you some CSS rules and pseudo-classes that will help you move your XPATH locator ...
- 无序数组的中位数(set+deque)hdu5249
KPI Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- [转]Chrome 控制台console的用法
Chrome 控制台console的用法 下面我们来看看console里面具体提供了哪些方法可以供我们平时调试时使用. 目前控制台方法和属性有: ["$$", "$x&q ...
- JS不兼容减号,css属性转驼峰写法
<script> function changeFormat(str) { return str.replace(/-(\w)/g, function(k, r) { return r.t ...