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 ...
随机推荐
- ICMP and InetAddress.isReachable()
In Java it is only possible to work with two types of sockets: stream based ones (or TCP ones - java ...
- C++11的for循环,以及范围Range类的实现
C++11支持range-based for循环.这是一个很方便的特性,能省挺多代码.以下代码就能很方便的遍历vector中的元素,并打印出来: 1 2 3 4 5 6 7 8 std::vector ...
- 如何在eclipse里使用git
新版都自带git插件了.在项目上右键,选team,选share project,再选择git就可以了. 如果在本地使用git比较简单.如果要多人共享的使用git,那么需要专门的服务器,并提供ssh,这 ...
- 【mysql的编程专题⑥】视图
视图是表的一个映射,是一张虚表,在结构上视图和普通的表没什么区别,一样可以用sql语句来增删改查; 视图创建后是一直存在数据库内 操作 创建视图 语法 CREATE [ALGORITHM]={UNDE ...
- spring 异常管理机制
三.异常处理的几种实现: 3.1.在经典的三层架构模型中,通常都是这样来进行异常处理的: A.持久层一般抛出的是RuntiomeException类型的异常,一般不处理,直接向上抛出. B.业务层一般 ...
- EXP-00091 Exporting questionable statistics
今天在我们对Oracle做EXP的过程中,出现EXP-00091 Exporting questionable statistics.的信息,但是也提示导出成功.最好查询了下发现其实它就是exp的er ...
- 【Lucene3.6.2入门系列】第04节_中文分词器
package com.jadyer.lucene; import java.io.IOException; import java.io.StringReader; import org.apach ...
- 分布式java应用
大型应用,通常会拆分为多个子系统来实现. 对Java来说,这些子系统可能部署在同一台机器的多个不同的JVM中,也可能部署在不同的机器上,但这些子系统又不是完全独立的,要相互通信来共同实现业 ...
- zip文件解压或压缩
<span style="font-size:18px;">/** * lsz */ public final class ZipUtil { /** * 解压zip文 ...
- 【转】Android设计中的.9.png
来源:http://isux.tencent.com/android-ui-9-png.html Android设计中的.9.png 注意:当使用9.png做TextView背景时,一定要设置内容区域 ...