HDU3966-Aragorn's Story(树链剖分)
第一道树链剖分。
早就想学。。一直懒。。
感觉还是比较简单的。
主要是要套其他数据结构,线段树大概还好,平衡树之类的肯定就跪了。
http://blog.csdn.net/acdreamers/article/details/10591443 这篇博客写的真的超级棒 简单明了
感觉树链剖分的难点就是更新的地方
看懂之后自己写一遍错误也都在那里>_<
树链剖分就是把数分成一个个链,然后首尾相连
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = ; //
struct Edge {
int to, next;
} edge[N*];
int head[N], cntE;
void addedge(int u, int v) {
edge[cntE].to = v; edge[cntE].next = head[u]; head[u] = cntE++;
edge[cntE].to = u; edge[cntE].next = head[v]; head[v] = cntE++;
}
//
int dep[N], sz[N], fa[N], son[N];
void dfs1(int u, int par, int d) {
dep[u] = d; sz[u] = ; fa[u] = par;
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (v != par) {
dfs1(v, u, d+);
sz[u] += sz[v];
if (son[u] == - || sz[v] > sz[son[u]]) son[u] = v;
}
}
}
int top[N], dfn[N], rk[N], idx;
void dfs2(int u, int rt) {
top[u] = rt; dfn[u] = ++idx; rk[idx] = u;
if (son[u] == -) return;
dfs2(son[u], rt);
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (v != fa[u] && v != son[u]) dfs2(v, v);
}
}
//
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
int sum[N<<], a[N];
void build(int o, int l, int r) {
if (l == r) { sum[o] = a[rk[l]]; return; }
int mid = (l+r) >> ;
build(lson); build(rson);
sum[o] = ;
} void pushdown(int o) {
if (sum[o]) {
sum[o<<] += sum[o];
sum[o<<|] += sum[o];
sum[o] = ;
}
} int query(int o, int l, int r, int v) {
if (l == r) return sum[o];
pushdown(o);
int mid = (l+r) >> ;
if (v <= mid) return query(lson, v);
return query(rson, v);
} void update(int o, int l, int r, int L, int R, int v) {
if (l >= L && r <= R) { sum[o] += v; return ; }
pushdown(o);
int mid = (l+r) >> ;
if (L <= mid) update(lson, L, R, v);
if (R > mid) update(rson, L, R, v);
} void change(int x, int y, int w, int n) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
update(, , n, dfn[top[x]], dfn[x], w);
x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
update(, , n, dfn[x], dfn[y], w);
} void init() {
idx = cntE = ;
memset(head, -, sizeof head);
memset(son, -, sizeof son);
} int main()
{
int n, m, p;
while (~scanf("%d%d%d", &n, &m, &p)) {
init();
int u, v, w;
char op[];
for (int i = ; i <= n; ++i) scanf("%d", &a[i]);
for (int i = ; i <= m; ++i) scanf("%d%d", &u, &v), addedge(u, v); dfs1(, , ); dfs2(, ); build(, , n); while (p--) {
scanf("%s", op);
if (*op == 'Q') {
scanf("%d", &u);
printf("%d\n", query(, , n, dfn[u]));
} else {
scanf("%d%d%d", &u, &v, &w);
if (*op == 'D') w = -w;
change(u, v, w, n);
}
}
}
return ;
}
HDU3966-Aragorn's Story(树链剖分)的更多相关文章
- hdu3966 Aragorn's Story 树链剖分
题目传送门 题目大意: 有n个兵营形成一棵树,给出q次操作,每一次操作可以使两个兵营之间的所有兵营的人数增加或者减少同一个数目,每次查询输出某一个兵营的人数. 思路: 树链剖分模板题,讲一下树链剖分过 ...
- HDU3669 Aragorn's Story 树链剖分 点权
HDU3669 Aragorn's Story 树链剖分 点权 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: n个点的,m条边,每个点都 ...
- HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树
HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...
- Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组
Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...
- HDU 3966 Aragorn's Story(树链剖分)(线段树区间修改)
Aragorn's Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- Hdu 3966 Aragorn's Story (树链剖分 + 线段树区间更新)
题目链接: Hdu 3966 Aragorn's Story 题目描述: 给出一个树,每个节点都有一个权值,有三种操作: 1:( I, i, j, x ) 从i到j的路径上经过的节点全部都加上x: 2 ...
- HDU 3966 Aragorn's Story 树链剖分+BIT区间修改/单点询问
Aragorn's Story Description Our protagonist is the handsome human prince Aragorn comes from The Lord ...
- hdu 3966 Aragorn's Story 树链剖分 按点
Aragorn's Story Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 3966 Aragorn's Story (树链剖分入门题)
树上路径区间更新,单点查询. 线段树和树状数组都可以用于本题的维护. 线段树: #include<cstdio> #include<iostream> #include< ...
- HDU 3966 Aragorn's Story 树链剖分
Link: http://acm.hdu.edu.cn/showproblem.php?pid=3966 这题注意要手动扩栈. 这题我交g++无限RE,即使手动扩栈了,但交C++就过了. #pragm ...
随机推荐
- C: 数组形参
知识这个东西,真是知道的越多就不知道的越多,C/C++这塘水得多深啊,哈哈.看下面3个片段:<一> 1 void fun(char a[100]) { 2 fprintf( ...
- linux 深入检测io详情的工具iopp
1.为什么推荐iopp iotop对内核及python版本都有一定要求,有时候无法用上,这时候就可以使用iopp作为替代方案.在有些情况下可能无法顺利使用iotop,这时候就可以选择iopp了.它的作 ...
- jvisualvm 使用
和jconsole侧重于内存分析和检测不同,jvisualvm在线程分析方面更强大一些,下面简单介绍下使用: 1. 在要监控的java应用配置文件中,本例是apache-jmeter/bin/jmet ...
- CentOS7 64位 自动分配IP地址设置
vim /etc/sysconfig/network-scripts/ifcfg-eno16777736 # ifcfg-后接网卡名称 配置如下,ONBOOT设置为yes HWADDR=:0C::E9 ...
- 为Windows 7添加“Internet打印”功能
http://wangchunhai.blog.51cto.com/225186/1156589/
- Oracle EBS PO 收接事处理状态待定或错误
PO接收后,发现在没有接收成功.在"事务处理状态汇总"查找到不是"待定"就是"错误",如下图: 对于事务处理状态"待定&quo ...
- 学Android开发 这19个开发工具助你顺风顺水
学Android开发 这19个开发工具助你顺风顺水 要想快速开发一个Android应用,通常会用到很多工具,巧妙利用这些工具,能让我们的开发工作事半功倍,节省大量时间,下面大连Android开发培训小 ...
- 函数buf_LRU_free_block
/******************************************************************//** Try to free a block. If bpag ...
- Mint Linuxubuntu 字体配置文件
<?xml version="1.0"?><!DOCTYPE fontconfig SYSTEM "fonts.dtd"><fon ...
- android studio 安装总结
Android Studio 的安装和配置篇(Windows篇<转> http://www.jianshu.com/p/fc03942548cc# 中间gradle下载比较慢:解决方法 需 ...