第一道树链剖分。

早就想学。。一直懒。。

感觉还是比较简单的。

主要是要套其他数据结构,线段树大概还好,平衡树之类的肯定就跪了。

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(树链剖分)的更多相关文章

  1. hdu3966 Aragorn's Story 树链剖分

    题目传送门 题目大意: 有n个兵营形成一棵树,给出q次操作,每一次操作可以使两个兵营之间的所有兵营的人数增加或者减少同一个数目,每次查询输出某一个兵营的人数. 思路: 树链剖分模板题,讲一下树链剖分过 ...

  2. HDU3669 Aragorn's Story 树链剖分 点权

    HDU3669 Aragorn's Story 树链剖分 点权 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: n个点的,m条边,每个点都 ...

  3. HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树

    HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...

  4. Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组

    Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...

  5. HDU 3966 Aragorn's Story(树链剖分)(线段树区间修改)

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. Hdu 3966 Aragorn's Story (树链剖分 + 线段树区间更新)

    题目链接: Hdu 3966 Aragorn's Story 题目描述: 给出一个树,每个节点都有一个权值,有三种操作: 1:( I, i, j, x ) 从i到j的路径上经过的节点全部都加上x: 2 ...

  7. HDU 3966 Aragorn's Story 树链剖分+BIT区间修改/单点询问

    Aragorn's Story Description Our protagonist is the handsome human prince Aragorn comes from The Lord ...

  8. hdu 3966 Aragorn's Story 树链剖分 按点

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  9. HDU 3966 Aragorn's Story (树链剖分入门题)

    树上路径区间更新,单点查询. 线段树和树状数组都可以用于本题的维护. 线段树: #include<cstdio> #include<iostream> #include< ...

  10. HDU 3966 Aragorn's Story 树链剖分

    Link: http://acm.hdu.edu.cn/showproblem.php?pid=3966 这题注意要手动扩栈. 这题我交g++无限RE,即使手动扩栈了,但交C++就过了. #pragm ...

随机推荐

  1. php析构函数

    <?php class Page { function __destruct() { echo "__destruct methor invokes<br>"; ...

  2. 188. Best Time to Buy and Sell Stock IV

    题目: 链接: 题解: 测试: Reference:

  3. 7个鲜为人知却超实用的PHP函数

    PHP有许多内置函数,其中大多数函数都被程序员广泛使用.但也有一些函数隐藏在角落,本文将向大家介绍7个鲜为人知,但用处非常大的函数. 没用过的程序员不妨过来看看. 1.highlight_string ...

  4. log file sync

    Recently, our application system has updated one app. I receive a email of complain the db server ch ...

  5. python 中@property的使用

    从14年下半年开始接触到python,自学了一段时间,后又跟别人学习了下,把基础知识基本上学过了.忽然感觉python不可能这么简单吧,就这么点东西?后来看了下书,发现还有很多的高级部分.连续看了两天 ...

  6. 1306.Sequence Median(堆排序)

    1306 URAL真是没水题 以为简单的排序就好了 ME  内存限制很紧 堆排序 或者 STL 用堆排序做的 正好复习一下 都忘了 #include <iostream> #include ...

  7. poj3257

    dp,先将材料按以终点为关键字升序排 设f[i,j]为过山车到建到位置i在用了j元钱所得到的最大价值,然后 ..] of longint; f:..,..] of longint; l,n,k,m,j ...

  8. LeetCode Summary Ranges (统计有序数列范围)

    题意:给出个有序不重复数列(可能负数),用缩写法记录这个数列. 思路:找每个范围的起始和结束即可. class Solution { public: vector<string> summ ...

  9. apache开源项目--OpenMeetings

    OpenMeetings是一个多语言可定制的视频会议和协作系统.它支持音频.视频,能让你查看每个与会者的桌面.OpenMeetings还包含一个白板,通过白板可以导入各种格式的图片和涂鸦. 在线演示: ...

  10. sharepoint 2010 如何给文档库或自定义列表添加评论功能

    转:http://www.cfanz.cn/?c=article&a=read&id=40924 最近公司在知识库中,有一个需求,就是想要给文档添加评论功能,在sharepoint 2 ...