_bzoj1036 [ZJOI2008]树的统计Count【树链剖分】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1036
保存模版。
执行qmax与qsum操作,往上爬的时候最开始的代码出了点小问题,往上爬的点应该是dep[top[u]]更深的点,而不是dep[u]更深的点。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm> const int maxn = 30005; int n, q, t1, t2, root;
int head[maxn], to[maxn << 1], next[maxn << 1], lb, cnt;
int siz[maxn], dep[maxn], fa[maxn], id[maxn], heavy[maxn], v[maxn], top[maxn], a[maxn];
char opr[10];
struct Node {
int ql, qr, mx, sm;
} tree[maxn << 2]; inline void ist(int aa, int ss) {
to[lb] = ss;
next[lb] = head[aa];
head[aa] = lb;
++lb;
}
void dfs1(int r) {
siz[r] = 1;
dep[r] = dep[fa[r]] + 1;
int mx = 0, id = 0;
for (int j = head[r]; j != -1; j = next[j]) {
if (to[j] != fa[r]) {
fa[to[j]] = r;
dfs1(to[j]);
siz[r] += siz[to[j]];
if (siz[to[j]] > mx) {
mx = siz[id = to[j]];
}
}
}
heavy[r] = id;
}
void dfs2(int r, int tp) {
if (!r) {
return;
}
top[r] = tp;
id[r] = ++cnt;
a[cnt] = v[r];
dfs2(heavy[r], tp);
for (int j = head[r]; j != -1; j = next[j]) {
if (to[j] != fa[r] && to[j] != heavy[r]) {
dfs2(to[j], to[j]);
}
}
}
void make_tree(int p, int left, int right) {
tree[p].ql = left;
tree[p].qr = right;
if (left == right) {
tree[p].mx = tree[p].sm = a[left];
return;
}
int mid = (left + right) >> 1;
make_tree(p << 1, left, mid);
make_tree(p << 1 | 1, mid + 1, right);
tree[p].mx = std::max(tree[p << 1].mx, tree[p << 1 | 1].mx);
tree[p].sm = tree[p << 1].sm + tree[p << 1 | 1].sm;
}
void upd(int p, int r, int value) {
if (tree[p].ql == tree[p].qr) {
tree[p].mx = tree[p].sm = value;
return;
}
int mid = (tree[p].ql + tree[p].qr) >> 1;
if (r <= mid) {
upd(p << 1, r, value);
}
else {
upd(p << 1 | 1, r, value);
}
tree[p].mx = std::max(tree[p << 1].mx, tree[p << 1 | 1].mx);
tree[p].sm = tree[p << 1].sm + tree[p << 1 | 1].sm;
}
int getmax(int p, int left, int right) {
if (tree[p].ql == left && tree[p].qr == right) {
return tree[p].mx;
}
int mid = (tree[p].ql + tree[p].qr) >> 1;
if (right <= mid) {
return getmax(p << 1, left, right);
}
if (left > mid) {
return getmax(p << 1 | 1, left, right);
}
return std::max(getmax(p << 1, left, mid), getmax(p << 1 | 1, mid + 1, right));
}
int getsum(int p, int left, int right) {
if (tree[p].ql == left && tree[p].qr == right) {
return tree[p].sm;
}
int mid = (tree[p].ql + tree[p].qr) >> 1;
if (right <= mid) {
return getsum(p << 1, left, right);
}
if (left > mid) {
return getsum(p << 1 | 1, left, right);
}
return getsum(p << 1, left, mid) + getsum(p << 1 | 1, mid + 1, right);
}
int qmax(int u, int v) {
int rt = -2147483646;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) {
std::swap(u, v);
}
rt = std::max(rt, getmax(1, id[top[u]], id[u]));
u = fa[top[u]];
}
if (dep[u] < dep[v]) {
std::swap(u, v);
}
rt = std::max(rt, getmax(1, id[v], id[u]));
return rt;
}
int qsum(int u, int v) {
int rt = 0;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) {
std::swap(u, v);
}
rt += getsum(1, id[top[u]], id[u]);
u = fa[top[u]];
}
if (dep[u] < dep[v]) {
std::swap(u, v);
}
rt += getsum(1, id[v], id[u]);
return rt;
} int main(void) {
//freopen("in.txt", "r", stdin);
unsigned seed;
memset(head, -1, sizeof head);
memset(next, -1, sizeof next);
scanf("%d", &n);
seed += n;
for (int i = 1; i < n; ++i) {
scanf("%d%d", &t1, &t2);
ist(t1, t2);
ist(t2, t1);
seed += t1;
}
for (int i = 1; i <= n; ++i) {
scanf("%d", v + i);
} srand(seed);
root = rand() % n + 1;
dfs1(root);
dfs2(root, root);
make_tree(1, 1, n); scanf("%d", &q);
while (q--) {
scanf("%s%d%d", opr, &t1, &t2);
if (opr[1] == 'M') {
printf("%d\n", qmax(t1, t2));
}
else if (opr[1] == 'S') {
printf("%d\n", qsum(t1, t2));
}
else {
upd(1, id[t1], t2);
}
}
return 0;
}
_bzoj1036 [ZJOI2008]树的统计Count【树链剖分】的更多相关文章
- BZOJ 1036: [ZJOI2008]树的统计Count [树链剖分]【学习笔记】
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 14302 Solved: 5779[Submit ...
- 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分
[BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...
- Bzoj 1036: [ZJOI2008]树的统计Count 树链剖分,LCT
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 11102 Solved: 4490[Submit ...
- BZOJ 1036: [ZJOI2008]树的统计Count( 树链剖分 )
树链剖分... 不知道为什么跑这么慢 = = 调了一节课啊跪.. ------------------------------------------------------------------- ...
- bzoj1036 [ZJOI2008]树的统计Count 树链剖分模板题
[ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成 一些操作: I. CHANGE u ...
- 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 ...
- 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 树链剖分模版题,打的时候注意点就行.做这题的时候,真的傻了,单词拼错检查了一个多小时 ...
随机推荐
- Java实现拖拽上传
原文:http://www.open-open.com/code/view/1437358795584 在项目开发中由于实际需求,需要开发拖拽上传的功能,ok! 先看效果图: jsp上传前端代码: & ...
- 【APUE】进程基础
进程标识符:非负整数 ID为0的进程通常是是调度进程,常被称为交换进程.该进程是内核的一部分,它并不执行任何磁盘上的程序,因此也被称为系统进程 ID为1的进程是init进程,在自举过程结束时由内核调用 ...
- hibernate查询之Criteria实现分页方法(GROOVY语法)
public int searchTest(String name, Integer pageIndex, List<Test> resultList){ def criteria = T ...
- Please enter a commit message to explain why this merge is necessary.
Please enter a commit message to explain why this merge is necessary. 请输入提交消息来解释为什么这种合并是必要的 git 在pul ...
- Dubbo应用启动与停止脚本,超具体解析
本周刚好研究了一下dubbo的启动脚本,所以在官网的启动脚本和公司内部的启动脚本做了一个整理,弄了一份比較通过的Dubbo应用启动和停止脚本. 以下的脚本仅仅应用于配置分离的应用.什 ...
- exadata(ilom) 练习
Oracle(R) Integrated Lights Out Manager Version 3.0.16.10 r65138 Copyright (c) 2011, Oracle and/or i ...
- 头文件与cpp文件为什么要分开写
最表面的机制是: 头文件是程序的界面(是代码界面),提供给程序员以 类.模版.函数等一系列的声明,让程序员知道应该怎么调用里面的"东西". 从动态链接库的角度看: 头文件提供界面 ...
- mp3 pcm
mp3 pcm javaMP3转pcm 百度语音识别 - 且学且珍惜 - SegmentFault 思否 https://segmentfault.com/a/1190000013383967
- Swift入门(十)——循环引用、弱引用和无主引用
近期看到swift里面不仅有循环引用和弱引用(weak),还加入了无主引用(unowned),于是写了一些demo,这里总结一下. 和OC一样.Swfit默认也是基于ARC进行内存管理的,因此尽管简单 ...
- 设计模式-(18)命令模式 (swift版)
一,概念: 在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”.但在某些场合,比如要对行为进行“记录.撤销/重做.事务”等处理,这种无法抵御变化的紧耦合是不合适的.在这种情况下,如何将 ...