[BZOJ4034] [HAOI2015] T2 (树链剖分)
Description
Input
Output
对于每个询问操作,输出该询问的答案。答案之间用换行隔开。
Sample Input
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
Sample Output
9
13
HINT
对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不会超过 10^6 。
Source
Solution
树链剖分,用线段树维护点权;对子树的修改就是区间修改,因为其dfs序是连续的
#include <bits/stdc++.h>
using namespace std;
struct edge
{
int v, nxt;
}e[];
struct point
{
int val, siz, fa, son, dfn, top;
}p[];
struct seg
{
long long val, lazy;
}a[];
int fst[], ptot; void addedge(int i, int u, int v)
{
e[i] = (edge){v, fst[u]}, fst[u] = i;
} void DFS1(int u)
{
p[u].siz = ;
for(int i = fst[u]; i; i = e[i].nxt)
if(p[u].fa != e[i].v)
{
p[e[i].v].fa = u;
DFS1(e[i].v);
p[u].siz += p[e[i].v].siz;
if(p[e[i].v].siz > p[p[u].son].siz)
p[u].son = e[i].v;
}
} void DFS2(int u, int top)
{
p[u].dfn = ++ptot, p[u].top = top;
if(p[u].son) DFS2(p[u].son, top);
for(int i = fst[u]; i; i = e[i].nxt)
if(e[i].v != p[u].fa && e[i].v != p[u].son)
DFS2(e[i].v, e[i].v);
} void push_up(int o, int l, int r)
{
a[o].val = a[o << ].val + a[o << | ].val;
a[o].val += a[o].lazy * (r - l + );
} void push_down(int o, int l, int r)
{
int mid = (l + r) >> ;
if(l == r) return;
if(a[o].lazy)
{
a[o << ].lazy += a[o].lazy;
a[o << ].val += a[o].lazy * (mid - l + );
a[o << | ].lazy += a[o].lazy;
a[o << | ].val += a[o].lazy * (r - mid);
a[o].lazy = ;
}
} void update(int o, int l, int r, int ql, int qr, int val)
{
int mid = (l + r) >> ;
push_down(o, l, r);
if(ql <= l && r <= qr)
{
a[o].lazy += val;
a[o].val += (long long)val * (r - l + );
return;
}
if(ql <= mid) update(o << , l, mid, ql, qr, val);
if(mid < qr) update(o << | , mid + , r, ql, qr, val);
push_up(o, l, r);
} long long query(int o, int l, int r, int ql, int qr)
{
int mid = (l + r) >> ;
long long ans = ;
push_down(o, l, r);
if(ql <= l && r <= qr) return a[o].val;
if(ql <= mid) ans = query(o << , l, mid, ql, qr);
if(mid < qr) ans += query(o << | , mid + , r, ql, qr);
return ans;
} int main()
{
int n, m, u, v, op, x, val;
long long ans;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; ++i)
scanf("%d", &p[i].val);
for(int i = ; i < n; ++i)
{
scanf("%d%d", &u, &v);
addedge(i << , u, v);
addedge(i << | , v, u);
}
DFS1(), DFS2(, );
for(int i = ; i <= n; ++i)
update(, , n, p[i].dfn, p[i].dfn, p[i].val);
while(m--)
{
scanf("%d", &op);
if(op == )
{
scanf("%d%d", &x, &val);
update(, , n, p[x].dfn, p[x].dfn, val);
}
else if(op == )
{
scanf("%d%d", &x, &val);
update(, , n, p[x].dfn, p[x].dfn + p[x].siz - , val);
}
else
{
scanf("%d", &x);
ans = ;
while(x)
{
ans += query(, , n, p[p[x].top].dfn, p[x].dfn);
x = p[p[x].top].fa;
}
printf("%lld\n", ans);
}
}
return ;
}
[BZOJ4034] [HAOI2015] T2 (树链剖分)的更多相关文章
- 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( 树链剖分 )
树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了 ------------------------------------------------------------------ ...
- JZYZOJ1539[haoi2015]T2 树链剖分
http://172.20.6.3/Problem_Show.asp?id=1539 在学校的OJ又写了一次,RE了好多次,原来haoi的时候这道题需要开栈+快读,裸数据结构30分,加上快读50分.o ...
- bzoj4034 树上操作 树链剖分+线段树
题目传送门 题目大意: 有一棵点数为 N 的树,以点 1 为根,且树点有权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有 ...
- BZOJ 4034 [HAOI2015]树上操作(树链剖分)
题目链接 BZOJ4034 这道题树链剖分其实就可以了. 单点更新没问题. 相当于更新 [f[x], f[x]]这个区间. f[x]表示树链剖分之后每个点的新的标号. 区间更新的话类似DFS序,求出 ...
- bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
- bzoj4034[HAOI2015]树上操作 树链剖分+线段树
4034: [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 6163 Solved: 2025[Submit][Stat ...
- BZOJ4034 [HAOI2015]树上操作 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4034 题意概括 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三 ...
- BZOJ 4034 [HAOI2015]T2(树链剖分)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4034 [题目大意] 有一棵点数为 N 的树,以点 1 为根,且树点有边权. 有 M 个 ...
随机推荐
- shell编程之SHELL基础(1)
shell脚本基础 shell是一个命令行解释器,她为互用提供了一个想linux内核发送请求以便运行程序的界面系统级程序,用户可以用shell来启动.挂起.停止甚至编写一些程序. shell还是一个功 ...
- Math.abs(~2018),掌握规律!
Math.abs(~2018) 这要用到一些计算机的基础知识. Math.abs(x)指的是返回一个数的绝对值,而关键在"~2018",这是取反操作符,故取相反数得结果为-2018 ...
- 利用Jsonp实现跨域请求,spring MVC+JQuery
1 什么是Jsonp? JSONP(JSON with Padding)是数据格式JSON的一种"使用模式",可以让网页从别的网域要数据.另一个解决这个问题的新方法是跨来源资源共享 ...
- nginx虚拟域名的配置以及测试验证
1.保证该机器上安装了nginx 未安装请看:centos/linux下的安装Nginx 2.使用root用户编辑配置文件 vim /usr/local/nginx/conf/nginx.conf 3 ...
- RegExp正则表达式规则以及常用正则表达式
html,body { font-family: "SF UI Display", ".PingFang SC", "PingFang SC" ...
- HDU - 1584 IDA*
思路:裸的IDA*,估计当前状态至少需要多少距离才能达到目标状态,剪枝即可.每一墩牌只需记录其最上面和最下面的牌型即可完成移动. AC代码 #include <cstdio> #inclu ...
- hive上mysql元数据库配置
hive调试信息显示模式: ./hive -hiveconf hive.root.logger=DEBUG,console 非常有用. 默认情况下,Hive元数据保存在内嵌的 Derby 数据库中,只 ...
- 解决ios不支持按钮:active伪类的方法
mozilla开发社区上有 :active 不起作用的答案: [1] By default, Safari Mobile does not use the :active state unless t ...
- 使用tcpcopy导入线上流量进行功能和压力测试
- 假设我们要上线一个两年内不会宕机的先进架构.在上线前,免不了单元测试,功能测试,还有使用ab,webbench等等进行压力测试. 但这些步骤非生产环境下正式用户的行为.或许你会想到灰度上线,但毕竟 ...
- linux kvm虚拟机快速构建及磁盘类型
KVM命令管理 virsh命令:用来管理各虚拟机的接口命令查看/创建/停止/关闭...支持交互模式格式:virsh 控制指令 [虚拟机名称] [参数] [root@room1pc01 桌面]# vir ...