#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;
#define N 50010
#define M 100010
int n, m, p;
class Node
{
public:
int fa, top, pos, val, siz, heavySon, dep;
};
Node node[N];
class Edge
{
public:
int u, v, next;
};
Edge edge[M];
int head[N], cnte, tree[N*4], seq[N], seqP;
void addEdge(int u, int v)
{
edge[cnte].u = u; edge[cnte].v = v;
edge[cnte].next = head[u]; head[u] = cnte++;
}
void dfs_1(int root, int fa, int d)
{
node[root].dep = d;
node[root].siz = 1;
int p = 0, val = -1;
node[root].fa = fa;
for(int i = head[root]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if(v != fa)
{
node[v].dep = node[root].dep+1;
dfs_1(v, root, d+1);
node[root].siz += node[v].siz;
if(node[v].siz > val)
{
p = v;
val = node[v].siz;
}
}
}
node[root].heavySon = p;
}
void dfs_2(int root, int tp)
{
node[root].top = tp;
node[root].pos = ++seqP;
seq[seqP] = root;
if(node[root].heavySon == 0) return;
dfs_2(node[root].heavySon, tp);
for(int i = head[root]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if(v != node[root].fa && v != node[root].heavySon)
{
dfs_2(v, v);
}
}
}
void build(int p, int l, int r)
{
if(l == r)
{
tree[p] = node[seq[l]].val;
return;
}
int mid = (l+r)>>1;
build(p<<1, l, mid);
build(p<<1|1, mid+1, r);
}
void update(int p, int l, int r, int x, int y, int delta)
{
if(x <= l && y >= r)
{
tree[p] += delta;
return;
}
tree[p<<1] += tree[p];
tree[p<<1|1] += tree[p];
tree[p] = 0;
int mid = (l+r)>>1;
if(x <= mid)
update(p<<1, l, mid, x, y, delta);
if(y >= mid+1)
update(p<<1|1, mid+1, r, x, y, delta);
}
int query(int p, int l, int r, int x)
{
if(l == r)
{
return tree[p];
}
tree[p<<1] += tree[p];
tree[p<<1|1] += tree[p];
tree[p] = 0;
int mid = (l+r)>>1;
if(x <= mid)
return query(p<<1, l, mid, x);
else return query(p<<1|1, mid+1, r, x);
}
void modify(int u, int v, int w)
{
while(node[u].top != node[v].top)
{
if(node[node[u].top].dep < node[node[v].top].dep)
swap(v, u);
update(1, 1, n, node[node[u].top].pos, node[u].pos, w);
u = node[node[u].top].fa;
}
if(node[u].dep > node[v].dep)
{
swap(u, v);
}
update(1, 1, n, node[u].pos, node[v].pos, w);
}
int main()
{
//freopen("C:\\Users\\zfh\\Desktop\\in.txt", "r", stdin);
while(scanf("%d%d%d", &n, &m, &p) != -1)
{
cnte = 0; seqP = 0;
memset(head, -1, sizeof head);
for(int i = 1; i <= n; i++)
{
scanf("%d", &node[i].val);
}
int u, v, w;
for(int i = 0; i < n-1; i++)
{
scanf("%d%d", &u, &v);
addEdge(u, v);
addEdge(v, u);
}
dfs_1(1, -1, 0);
dfs_2(1, 1);
memset(tree, 0, sizeof tree);
build(1, 1, n);
char ch;
for(int i = 0; i < p; i++)
{
scanf(" %c", &ch);
if(ch == 'I')
{
scanf("%d%d%d", &u, &v, &w);
modify(u, v, w);
}
else if(ch == 'D')
{
scanf("%d%d%d", &u, &v, &w);
modify(u, v, -w);
}
else
{
scanf("%d", &u);
printf("%d\n", query(1, 1, n, node[u].pos));
}
}
}
return 0;
}
HDU 3966 树链剖分模板
最新推荐文章于 2019-09-16 15:46:17 发布