第一道树链剖分。

早就想学。。一直懒。。

感觉还是比较简单的。

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

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的strpos() 函数判断字符串中是否包含某字符串的方法

    判断某字符串中是否包含某字符串的方法 if(strpos('www.idc-gz.com','idc-gz') !== false){ echo '包含'; }else{ echo '不包含'; } ...

  2. <context:component-scan>配置解析(转)

    在xml配置了这个标签后,spring可以自动去扫描base-pack下和其子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注 ...

  3. 【转】VC++消息钩子编程

    VC++消息钩子编程

  4. pogo pin连接器塑胶部件的缺陷及产生原因分析

    pogo pin连接器塑胶部件异色.褪色产品的颜色与标准颜色不同的现象.与树脂颜色不同为异色:注塑后颜色发生改变的现象为变色. 产生的主要原因:1.着色错误(色粉有误) 2.树脂污染3.过多使用粉碎品 ...

  5. VMware 11完全安装Mac OS X 10.10

    本文已迁移到我的个人网站 http://www.wshunli.com 文章地址: http://www.wshunli.com/2016/03/17/VMware-12安装Mac-OS-X-10-1 ...

  6. SDIBT2666——逆波兰表达式求值

    逆波兰表达式求值(栈和队列) Description 从键盘上输入一个逆波兰表达式,用伪码写出其求值程序.规定:逆波兰表达式的长度不超过一行,以@符作为输入结束,操作数之间用空格分隔,操作符只可能有+ ...

  7. Android 监听EditView中的文本改变事件

    android中的编辑框EditText也比较常用,那比如在搜索框中,没输入一个字,下面的搜索列表就显示有包含输入关键字的选项,这个输入监听怎么实现的呢? 我们可以建一个例子,效果图如下: 我们可以监 ...

  8. 几种必知的oracle结构图

    一.数据库结构 二.Oracle 内存结构 三.进程结构 1. 用户进程:在数据库用户请求连接到Oracle 服务器时启动 2. 服务器进程:可以连接到Oracle实例,它在用户建立会话时启动 3. ...

  9. Android学习Service中遇到的问题

    今天学习service,然后遇到了一个force close,log中存在这个一句话: 05-23 14:13:26.408: E/AndroidRuntime(17616): android.con ...

  10. Windows 之间用rsync同步数据(cwRsyncServer配置)

    rsync是一款优秀的数据同步软件,在跨服务器,跨机房,跨国备份服务器的首选工具,下面就来介绍下如何配置安装cwRsyncServer很大多数软件一样是B/C架构,cwRsyncServer是rsyn ...