BZOJ4034——[HAOI2015]T2
1、题目大意:用一个数据结构支持树的点修改和子树修改、树上路径和
2、分析:树链剖分裸题
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1000000
#define LL long long
LL Size[M], value[M], Top[M], Fa[M], Height[M], num[M], left[M], right[M];
LL tot, ST_tot;
LL son[M], head[M], Next[M];
LL n, m;
LL q[M], lazy[M];
void init(){
memset(head, -1, sizeof(head));
memset(lazy, 0, sizeof(lazy));
tot = ST_tot = 0;
Top[1] = 1;
}
void pushdown(LL l, LL r, LL o){
LL mid = (l + r) / 2;
q[2 * o] += (mid + 1 - l) * lazy[o];
q[2 * o + 1] += (r - mid) * lazy[o];
lazy[2 * o] += lazy[o];
lazy[2 * o + 1] += lazy[o];
lazy[o] = 0;
}
void add(LL l, LL r, LL o, LL x, LL y, LL z){
if(x <= l && r <= y){
lazy[o] += z;
q[o] += (r - l + 1) * z;
return;
}
pushdown(l, r, o);
LL mid = (l + r) / 2;
if(x <= mid) add(l, mid, 2 * o, x, y, z);
if(y > mid) add(mid + 1, r, 2 * o + 1, x, y, z);
q[o] = q[2 * o] + q[2 * o + 1];
}
LL query(LL l, LL r, LL o, LL x, LL y){
if(x <= l && r <= y) return q[o];
pushdown(l, r, o);
LL mid = (l + r) / 2, ret = 0;
if(x <= mid) ret += query(l, mid, 2 * o, x, y);
if(y > mid) ret += query(mid + 1, r, 2 * o + 1, x, y);
return ret;
}
void insert(LL x, LL y){
tot ++;
son[tot] = y;
Next[tot] = head[x];
head[x] = tot;
}
void dfs1(LL x, LL fa, LL height){
Fa[x] = fa;
Height[x] = height;
Size[x] = 1;
for(LL i = head[x]; i != -1; i = Next[i]) if(son[i] != fa){
dfs1(son[i], x, height + 1);
Size[x] += Size[son[i]];
}
}
void dfs2(LL x, LL fa){
++ ST_tot;
left[x] = ST_tot;
num[x] = ST_tot;
add(1, n, 1, ST_tot, ST_tot, value[x]);
LL o = 0, ss = 0;
for(LL i = head[x]; i != -1; i = Next[i]) if(son[i] != fa){
if(Size[son[i]] > ss){
ss = Size[son[i]];
o = i;
}
}
if(o != 0){
Top[son[o]] = Top[x];
dfs2(son[o], x);
}
for(LL i = head[x]; i != -1; i = Next[i]) if(son[i] != fa && o != i){
Top[son[i]] = son[i];
dfs2(son[i], x);
}
right[x] = ST_tot;
}
void real_add(LL x, LL y){
add(1, n, 1, left[x], right[x], y);
}
void real_add1(LL x, LL y){
add(1, n, 1, num[x], num[x], y);
}
LL real_query(LL x){
LL y = 1;
LL ret = 0;
while(Top[x] != Top[y]){
if(Height[Top[x]] < Height[Top[y]]) swap(x, y);
ret += query(1, n, 1, num[Top[x]], num[x]);
x = Fa[Top[x]];
}
if(Height[x] < Height[y]) swap(x, y);
ret += query(1, n, 1, num[y], num[x]);
return ret;
}
int main(){
scanf("%lld%lld", &n, &m);
for(LL i = 1; i <= n; i ++) scanf("%lld", &value[i]);
init();
for(LL i = 1; i < n; i ++){
LL x, y;
scanf("%lld%lld", &x, &y);
insert(x, y);
insert(y, x);
}
dfs1(1, 0, 1);
dfs2(1, 0);
for(LL i = 1; i <= m; i ++){
LL op, x, a;
scanf("%lld", &op);
if(op == 1){
scanf("%lld%lld", &x, &a);
real_add1(x, a);
}
else if(op == 2){
scanf("%lld%lld", &x, &a);
real_add(x, a);
}
else{
scanf("%lld", &x);
printf("%lld\n", real_query(x));
}
}
return 0;
}
BZOJ4034——[HAOI2015]T2的更多相关文章
- bzoj4034: [HAOI2015]T2
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 2684 Solved: 843 Description 有一 ...
- [BZOJ4034] [HAOI2015] T2 (树链剖分)
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...
- 【DFS序】【线段树】bzoj4034 [HAOI2015]T2
分开维护树的入栈序和出栈序,用两棵线段树.回答时就是用一颗的减去另一棵的. #include<cstdio> #include<algorithm> using namespa ...
- bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
- Bzoj 4034: [HAOI2015]T2 树链剖分,子树问题,dfs序
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1841 Solved: 598[Submit][Status] ...
- BZOJ 4034: [HAOI2015]T2( 树链剖分 )
树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了 ------------------------------------------------------------------ ...
- bzoj 4034: [HAOI2015]T2
4034: [HAOI2015]T2 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操 ...
- 【bzoj4034】[HAOI2015]T2
siz[v]表示以v为根的子树的节点数 top[v]表示v所在的重链的顶端节点 fa[v]表示v的父亲 pos[v]表示v的父边标号 mx[v]表示v的子树中边的标号最大的那条边 参考:http:// ...
- 数据结构(树链剖分):BZOJ 4034: [HAOI2015]T2
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
随机推荐
- 深入理解css中的margin属性
深入理解css中的margin属性 之前我一直认为margin属性是一个非常简单的属性,但是最近做项目时遇到了一些问题,才发现margin属性还是有一些“坑”的,下面我会介绍margin的基本知识以及 ...
- C++中int,float,string,char*的转换(待续)
//float转string char a[100]; float b = 1.234; sprintf(a, "%f", b); string result(a); //int转 ...
- 获取字符串中每个字符出现的次数(利用TreeMap)
案例:"aababcabcdabcde",获取字符串中每一个字母出现的次数要求结果:a(5)b(4)c(3)d(2)e(1)分析1:定义一个字符串(可以改进为键盘录入)2:定义一个 ...
- JavaWeb学习笔记——XML解析
DOM解析操作 只在跟节点<addresslist>下面建立一个子节点<name> <?xml version="1.0" encoding=&quo ...
- docker中启动mysql报错
[root@5416ec39653b init.d]# /etc/init.d/mysqld start /etc/init.d/mysqld: line 23: /etc/sysconfig/net ...
- win10系统点击关机按钮后无法关机的解决办法
先吐槽下:我越发的发现我现在成了修电脑的了,我的职位是linux运维,现在干的活很蛋疼,公司只有我一个运维,修电脑.搞网络.抬服务器.弄监控,搭环境.搞自动化发布.弄虚拟化都我一个人哇.好了,打住. ...
- PHP站内搜索、多关键字、加亮显示
php搜索代码: 搜索以PHP100开头: SELECT * FROM teble WHERE title LIKE 'PHP100%' 搜索以PHP100结束: SELECT * FROM te ...
- Http常用状态码
HTTP状态码(HTTP Status Code) 一些常见的状态码为: 200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - 服务不可用 所有状态解释:点击查看 1xx(临时响应 ...
- git之https或http方式设置记住用户名和密码的方法
https方式每次都要输入密码,按照如下设置即可输入一次就不用再手输入密码的困扰而且又享受https带来的极速 设置记住密码(默认15分钟): git config --global credenti ...
- php打印数组 --- 打印出漂亮格式的数组
htm的<pre>标签,能非常标准的显示数组格式 echo "<pre>";print_r($arr);echo "<pre>&quo ...