您的位置:首页 > 编程语言 > Go语言

hdu 3966 Aragorn's Story(树连剖分)

2013-09-24 18:49 260 查看
树连剖分,线段树

树链剖分的核心就是将树线性化,从而简化对其的操作

#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 50010;
#ifndef __GNUC__
#pragma comment(linker, "/STACK:1024000000,1024000000")
#endif // __GNUC__
int n, m, q;
int cn_tree;
struct _edge
{
int to, next;
}edge[MAXN<<1];
int head[MAXN], cn_edge;
int son[MAXN], siz[MAXN], top[MAXN], fa[MAXN], dep[MAXN];
char tpc[10];
int pos_tree[MAXN];
int num[MAXN];
void init()
{
memset(head, -1, sizeof head);
cn_edge = 0;
cn_tree = 0;
top[0] = 0, siz[0] = 0, son[0] = 0; fa[0] = 0;
dep[0] = 0;
}
void add(int u, int v)
{
edge[cn_edge].to = v; edge[cn_edge].next = head[u];
head[u] = cn_edge++;
}
void dfs1(int u, int pre)
{
fa[u] = pre;
dep[u] = dep[pre] + 1;
siz[u] = 1;
son[u] = 0;
for (int i = head[u]; ~i; i = edge[i].next)
{
int v = edge[i].to;
if (v == pre) continue;
dfs1(v, u);
siz[u] += siz[v];
if (siz[son[u]] < siz[v])
son[u] = v;
}
}
void dfs2(int u, int p)
{
top[u] = p;
pos_tree[u] = ++cn_tree;
if (!son[u]) return;
dfs2(son[u], p);
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 lr rot<<1
#define rr (rot<<1)|1
#define lson l,m,lr
#define rson m+1,r,rr
#define mid m=(l+r)>>1;
int num_add[MAXN<<2];
void pushDOWN(int l, int r, int rot)
{
if (l == r) return;
num_add[lr] += num_add[rot];
num_add[rr] += num_add[rot];
num_add[rot]= 0;
}
void build(int l, int r, int rot)
{
num_add[rot] = 0;
if (l == r) return ;
int mid;
build(lson);
build(rson);
}
void update(int L, int R, int val, int l, int r, int rot)
{
if ( L <= l && R >= r)
{
num_add[rot] += val;
return;
}
pushDOWN(l,r,rot);
int mid;
if (L <= m ) update(L,R,val,lson);
if (R > m) update(L,R,val,rson);
}
int query(int ps, int l, int r, int rot)
{
if ( l== r) return num_add[rot];
pushDOWN(l,r,rot);
int mid;
if (ps <= m) return query(ps, lson);
else return query(ps, rson);
}
void solve(int a, int b, int k)
{
while (top[a] != top[b])
{
if (dep[top[a]] < dep[top[b]]) swap(a, b);
update(pos_tree[top[a]], pos_tree[a], k, 1, n, 1);
a = fa[top[a]];
}
if (dep[a] > dep[b]) swap(a, b);
update(pos_tree[a], pos_tree[b], k, 1, n, 1);
}
int main()
{
#ifdef  __GNUC__
freopen ( "in.txt", "r", stdin );
#endif // __GNUC__
while (scanf("%d%d%d", &n, &m, &q) != EOF)
{
init();
for (int i = 1; i<=n; ++i) scanf("%d", num+i);
for (int i = 0; i< m; ++i)
{
int u, v;
scanf("%d%d", &u, &v);
add(u, v); add(v, u);
}
dfs1(1, 0);
dfs2(1, 1);
build(1,n,1);
while (q--)
{
scanf("%s", tpc);
if (tpc[0] == 'Q')
{
int val;
scanf("%d", &val);
printf("%d\n", num[val] + query(pos_tree[val], 1,n,1));
}
else
{
int l, r, v;
scanf("%d%d%d", &l, &r, &v);
if (tpc[0] == 'D') v= -v;
solve(l, r, v);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: