BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分+单点更新+区间求和+区间求最大值)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1036
题意:略。
题解:树链剖分模版,注意一些细节即可。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int M = 3e4 + 10;
struct Edge {
int v , next;
}edge[M << 1];
int head[M] , e;
int top[M];
int fa[M];
int p[M];
int fp[M];
int deep[M];
int num[M];
int son[M];
int pos;
void init() {
memset(head , -1 , sizeof(head));
memset(son , -1 , sizeof(son));
e = 0;
pos = 1;
}
void add(int u , int v) {
edge[e].v = v;
edge[e].next = head[u];
head[u] = e++;
}
void dfs1(int u , int pre , int d) {
deep[u] = d;
fa[u] = pre;
num[u] = 1;
for(int i = head[u] ; i != -1 ; i = edge[i].next) {
int v = edge[i].v;
if(v != pre) {
dfs1(v , u , d + 1);
num[u] += num[v];
if(son[u] == -1 || num[son[u]] < num[v]) {
son[u] = v;
}
}
}
}
void getpos(int u , int sp) {
top[u] = sp;
p[u] = pos++;
fp[p[u]] = u;
if(son[u] == -1) return ;
getpos(son[u] , sp);
for(int i = head[u] ; i != -1 ; i = edge[i].next) {
int v = edge[i].v;
if(v != fa[u] && v != son[u])
getpos(v , v);
}
}
struct TnT {
int l , r , sum , MAX;
}T[M << 2];
int a[M];
void pushup(int i) {
T[i].sum = T[i << 1].sum + T[(i << 1) | 1].sum;
T[i].MAX = max(T[i << 1].MAX , T[(i << 1) | 1].MAX);
}
void build(int l , int r , int i) {
int mid = (l + r) >> 1;
T[i].l = l , T[i].r = r , T[i].MAX = 0 , T[i].sum = 0;
if(l == r) {
T[i].MAX = a[fp[l]];
T[i].sum = a[fp[l]];
return ;
}
build(l , mid , i << 1);
build(mid + 1 , r , (i << 1) | 1);
pushup(i);
}
void updata(int i , int pos , int ad) {
int mid = (T[i].l + T[i].r) >> 1;
if(T[i].l == T[i].r && T[i].l == pos) {
T[i].MAX = ad;
T[i].sum = ad;
return ;
}
if(mid < pos) {
updata((i << 1) | 1 , pos , ad);
}
else {
updata(i << 1 , pos , ad);
}
pushup(i);
}
int queryM(int l , int r , int i) {
int mid = (T[i].l + T[i].r) >> 1;
if(T[i].l == l && T[i].r == r) {
return T[i].MAX;
}
pushup(i);
if(mid < l) {
return queryM(l , r , (i << 1) | 1);
}
else if(mid >= r) {
return queryM(l , r , i << 1);
}
else {
return max(queryM(l , mid , i << 1) , queryM(mid + 1 , r , (i << 1) | 1));
}
}
int queryS(int l , int r , int i) {
int mid = (T[i].l + T[i].r) >> 1;
if(T[i].l == l && T[i].r == r) {
return T[i].sum;
}
pushup(i);
if(mid < l) {
return queryS(l , r , (i << 1) | 1);
}
else if(mid >= r) {
return queryS(l , r , i << 1);
}
else {
return queryS(l , mid , i << 1) + queryS(mid + 1 , r , (i << 1) | 1);
}
}
int findM(int u , int v) {
int f1 = top[u] , f2 = top[v];
int tmp = -30010;
while(f1 != f2) {
if(deep[f1] < deep[f2]) {
swap(f1 , f2);
swap(u , v);
}
tmp = max(tmp , queryM(p[f1] , p[u] , 1));
u = fa[f1] , f1 = top[u];
}
if(deep[u] > deep[v]) swap(u , v);
return max(tmp , queryM(p[u] , p[v] , 1));
}
int findS(int u , int v) {
int f1 = top[u] , f2 = top[v];
int tmp = 0;
while(f1 != f2) {
if(deep[f1] < deep[f2]) {
swap(f1 , f2);
swap(u , v);
}
tmp += queryS(p[f1] , p[u] , 1);
u = fa[f1] , f1 = top[u];
}
if(deep[u] > deep[v]) swap(u , v);
return tmp + queryS(p[u] , p[v] , 1);
}
int main() {
int n , u , v , m;
scanf("%d" , &n);
init();
for(int i = 0 ; i < n - 1 ; i++) {
scanf("%d%d" , &u , &v);
add(u , v);
add(v , u);
}
for(int i = 1 ; i <= n ; i++) {
scanf("%d" , &a[i]);
}
dfs1(1 , 0 , 0);
getpos(1 , 1);
build(1 , pos , 1);
scanf("%d" , &m);
char cp[10];
while(m--) {
scanf("%s" , cp);
scanf("%d%d" , &u , &v);
if(cp[0] == 'Q') {
if(cp[1] == 'M') {
printf("%d\n" , findM(u , v));
}
else {
printf("%d\n" , findS(u , v));
}
}
else {
updata(1 , p[u] , v);
}
}
return 0;
}
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(Link Cut Tree,改动点权求两个最大值和最大值)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MB Submit: 8421 Solved: 3439 [Submi ...
- 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 ...
随机推荐
- 读JDK源码集合部分
以前读过一遍JDK源码的集合部分,读完了一段时间后忘了,直到有一次面试简历上还写着读过JDK集合部分的源码,但面试官让我说说,感觉记得不是很清楚了,回答的也模模糊糊的,哎,老了记性越来越差了,所以再回 ...
- S2:c#继承
在C#中,如果一个类后面通过冒号又跟了另外一个类,那么我们就称冒号前面的类为子类,冒号后面的类为父类.这种书写类的方式放映出来的关系就称为类的继承关系. 1.子类:派生类 父类:基类或者超类 满足is ...
- 微服务SpringCloud之Spring Cloud Config配置中心Git
微服务以单个接口为颗粒度,一个接口可能就是一个项目,如果每个项目都包含一个配置文件,一个系统可能有几十或上百个小项目组成,那配置文件也会有好多,对后续修改维护也是比较麻烦,就和前面的服务注册一样,服务 ...
- 手动编译PHP开发环境
目录 手动编译PHP开发环境 问题复盘 部署环境及配置 目标环境 安装部署环境开始 首先安装PHP 安装mysql 安装nginx 手动编译PHP开发环境 这是一篇来自深夜加班的手稿 问题复盘 你有没 ...
- java 各基本类型转 bytes 数组
java 将 基本类型转byte[] 数组时,需考虑大端小端问题 1. 大端格式下,基本类型与byte[]互转 BigByteUtil.java package com.ysq.util; impor ...
- C语言编程入门之--第五章C语言基本运算和表达式-part2
5.1.4 再来一个C库函数getchar吸收回车键 回车键也是一个字符,在使用scanf的时候,输入完毕要按下回车键,这时候回车键也会被输入到stdin流中,会搞乱我们的程序. 注意:stdin是输 ...
- web面试
什么是面向对象? 程序中的事物都是用对象结构来描述的,所有的程序都是用面向对象的思想,管理数据和功能的. 面向对象三大特点:封装 继承 多态 什么是封装? 创建一个对象结构,用来保存一个事物的属性和方 ...
- 实现ssr服务端渲染demo
最近在研究SSR服务器端渲染,自己写了的小demo. 项目布局 ├── build // 配置文件 │ │── webpack.base // 公共配置 │ │── webpack.clien ...
- 物流运输trans「ZJOI2006」
[题目描述] 物流公司要把一批货物从码头\(A\)运到码头\(B\).由于货物量比较大,需要\(n\)天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运 ...
- Simple Windows Service in C++
本文是来自CodeProject中的一篇名为Simple Windows Service in C++的译文,原文地址为:https://www.codeproject.com/Articles/49 ...