HDU 3966
树链剖分模板题
#include <bits/stdc++.h>
using namespace std;
const int maxn= 50010;
int n,m,q;
int c[maxn];
int head[maxn],cnt=0;
struct node
{
int to,next;
}edge[100005*2];
void add(int u,int v)
{
edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++;
}
int fa[maxn],son[maxn],much[maxn],deep[maxn];
int pos[maxn],ndfs[maxn],top[maxn],tot=0;
void dfs1(int u,int pre,int step)
{
fa[u]=pre;
much[u]=1;
deep[u]=step;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v!=pre)
{
dfs1(v,u,step+1);
much[u] += much[v];
if(son[u]==-1 || much[v] > much[son[u]]) son[u]=v;
}
}
}
void dfs2(int u,int pre)
{
top[u]= pre;
ndfs[u] = ++tot;
pos[ndfs[u]]=u;
if(son[u]==-1) return;
dfs2(son[u],pre);
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v!=son[u] && v!=fa[u])
{
dfs2(v,v);
}
}
}
#define lson rt<<1,begin,mid
#define rson rt<<1|1,mid+1,end
int tree[maxn<<2],lazy[maxn<<2];
void pushdown(int rt,int k)
{
if(lazy[rt])
{
int temp=lazy[rt];
tree[rt<<1] +=(k-(k>>1))*temp;
tree[rt<<1|1] += (k>>1)*temp;
lazy[rt<<1] += temp;
lazy[rt<<1|1] +=temp;
lazy[rt]=0;
}
}
void build(int rt,int begin,int end)
{
lazy[rt]=0;
if(begin==end)
{
tree[rt] = c[pos[begin]];
return;
}
int mid=(begin + end)>>1;
build(lson);
build(rson);
}
int query(int rt,int begin,int end,int pos)
{
if(begin == end)
{
return tree[rt];
}
pushdown(rt,end-begin+1);
int mid = (begin + end)>>1;
if(mid >= pos) return query(lson,pos);
else return query(rson,pos);
}
void updata(int rt,int begin,int end,int l,int r,int x)
{
if(begin >=l && r>=end)
{
lazy[rt]+=x;
tree[rt]+= x*(end-begin+1);
return;
}
pushdown(rt,end-begin+1);
int mid=(begin + end)>>1;
if(mid >= l) updata(lson,l,r,x);
if(r>mid) updata(rson,l,r,x);
}
void chang(int x,int y,int val)
{
while(top[x]!=top[y])
{
if(deep[top[x]] < deep[top[y]]) swap(x,y);
updata(1,1,n,ndfs[top[x]],ndfs[x],val);
x = fa[top[x]];
}
if(deep[x] > deep[y]) swap(x,y);
updata(1,1,n,ndfs[x],ndfs[y],val);
}
char s[25];
int main()
{
while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
memset(head,-1,sizeof(head)); cnt=0;
memset(son,-1,sizeof(son)); tot=0;
for(int i=1;i<=n;++i)
{
scanf("%d",&c[i]);
}
for(int i=1;i<=m;++i)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b); add(b,a);
}
dfs1(1,0,0);
dfs2(1,1);
build(1,1,n);
for(int i=1;i<=q;++i)
{
scanf("%s",s);
if(s[0]=='I')
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
chang(a,b,c);
}
else if(s[0]=='D')
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
chang(a,b,-c);
}
else if(s[0]=='Q')
{
int a;
scanf("%d",&a);
printf("%d\n",query(1,1,n,ndfs[a]));
}
}
}
return 0;
}