鏈接:http://acm.split.hdu.edu.cn/showproblem.php?pid=3966
題意:
給出一棵樹,
I C1 C2 K: 把C1與C2的路徑上的所有點權值加上K
D C1 C2 K:把C1與C2的路徑上的所有點權值減去K
Q C:查詢節點編號爲C的權值
題解:
樹鏈剖分
CODE:
#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define bug cout<<"bug"<<endl
const int MAXN = 50007;
const int MOD = 1e9 + 9;
int n,m,q;
int a[MAXN],deep[MAXN],siz[MAXN],far[MAXN],
son[MAXN],hit[MAXN],rev[MAXN],top[MAXN];
int num[MAXN],head[MAXN<<2],ind,sum[MAXN<<2],lazy[MAXN<<2];
struct node
{
int v,next;
}edge[MAXN<<2];
void add_edge(int u, int v)
{
edge[ind].v=v;
edge[ind].next=head[u];
head[u]=ind++;
}
int Dep2;
void dfs_size(int u, int fa,int d)
{
deep[u]=++d;
siz[u]=1;
far[u]=fa;
for(int i=head[u]; i+1; i=edge[i].next)
{
int v=edge[i].v;
if(v!=fa)
{
dfs_size(v,u,d);
siz[u]+=siz[v];
if(!son[u] || siz[v]>siz[ son[u] ])
son[u]=v;
}
}
}
void dfs_list(int u, int p)
{
top[u]=p;
hit[u]=++Dep2;
rev[Dep2]=u;
if(!son[u])return ;
dfs_list(son[u],p);
for(int i=head[u]; i+1; i=edge[i].next)
{
int v=edge[i].v;
if(v!=son[u] && v!=far[u])
dfs_list(v,v);
}
}
void push(int poi)
{
if(lazy[poi])
{
lazy[poi<<1]+=lazy[poi];
lazy[poi<<1^1]+=lazy[poi];
lazy[poi]=0;
}
}
void build(int poi, int l, int r)
{
lazy[poi]=0;
if(l==r)
{
sum[poi]=num[ rev[l] ];
return ;
}
int mid=(l+r)>>1;
sum[poi]=0;
build(poi<<1, l, mid);
build(poi<<1^1, mid+1, r);
}
void add(int poi, int l, int r, int val, int a, int b)
{
if(a<=l && r<=b){lazy[poi]+=val;return;}
push(poi);
int mid=(l+r)>>1;
if(mid>=a)add(poi<<1,l,mid,val,a,b);
if(b>mid)add(poi<<1^1,mid+1,r,val,a,b);
}
void find_list(int a, int b, int val)
{
while(top[a]!=top[b])
{
if(hit[ top[a] ] > hit[ top[b] ])swap(a,b);
add(1,1,n,val,hit[ top[b] ],hit[b]);
b=far[ top[b] ];
}
if(deep[a] > deep[b])swap(a,b);
add(1,1,n,val,hit[a],hit[b]);
}
int query(int poi, int l, int r, int p)
{
if(l==r)return sum[poi]+lazy[poi];
push(poi);
int mid=(l+r)>>1;
if(mid>=p)return query(poi<<1,l,mid,p);
return query(poi<<1^1,mid+1,r,p);
}
int main()
{
char str[3];
while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
int a,b,c;
Dep2=ind=0;
memset(head,-1,sizeof(head));
memset(son,0,sizeof(son));
for(int i=1; i<=n; ++i)
scanf("%d",&num[i]);
for(int i=1; i<=m; ++i)
{
scanf("%d%d",&a,&b);
add_edge(a,b);
add_edge(b,a);
}
dfs_size(1,0,0);
dfs_list(1,1);
build(1,1,n);
for(int i=0; i<q; ++i)
{
scanf("%s",str);
if(str[0]=='Q')
{
scanf("%d",&a);
printf("%d\n",query(1,1,n,hit[a]));
}
else
{
scanf("%d%d%d",&a,&b,&c);
if(str[0]=='D')c=-c;
find_list(a,b,c);
}
}
}
}
/*
3 2 5
1 2 3
2 1
2 3
I 1 3 5
Q 2
D 1 2 2
Q 1
Q 3
*/