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 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
随机推荐
- iptables (二) nat & tcp_wrapper
一.nat 之前网络防火墙的示例中,如果内网是私网地址,那么内网主机如何与外网通信呢? 这时候,iptables要实现内网和外网通信,有两种方式: nat: Network Address Trans ...
- Wannafly Camp 2020 Day 2B 萨博的方程式 - 数位dp
给定 \(n\) 个数 \(m_i\),求 \((x_1,x_2,...,x_n)\) 的个数,使得 \(x_1 \ xor\ x_2\ xor\ ...\ xor\ x_n = k\),且 \(0 ...
- laravle中常见的数据库加密
// 1.md5加密 $str=md5('123456'); // 2.base64_decode加密 $str2=base64_encode('123456'); // 2.1 base64_解密 ...
- redis测试题
1.什么是Redis? Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存. ...
- 为什么在linux系统下安装anaconda的时候会报错
报错界面 一开始是在官网下载的最新的包,出现了上述的报错,但是换成清华镜像之后,就没有上述报错了? 我猜测可能是因为 官网最新的版本的anaconda和你安装的python版本不兼容,而在镜像上的不是 ...
- chrome json接口数据 插件
chrome json接口数据 插件 JSON-Handle 官网 下载后 地址栏输入 chrome://extensions/ 将下载的文件拖入页面 OK
- data_analysis 第一课
1.anaconda的安装与使用 在官网下载anaconda的客户端,因为python有2和3之分,所以有两个版本可以供选择,由于该课程使用2作为开发工具,选择anaconda2下载安装. 安装好之后 ...
- Codeforces 540A - Combination Lock
Scrooge McDuck keeps his most treasured savings in a home safe with a combination lock. Each time he ...
- webservice后台起调试
https://blog.csdn.net/smile00_0/article/details/72763114
- [P5555] 秩序魔咒 - 回文自动机,DFS
#include <bits/stdc++.h> #define Sigma 30 #define MAXN 500010 #define int long long using name ...