3 2 5 1 2 3 2 1 2 3 I 1 3 5 Q 2 D 1 2 2 Q 1 Q 3
7 4 8Hint1.The number of enemies may be negative. 2.Huge input, be careful.
#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=50010;
typedef long long ll;
#define lson L,mid,ls
#define rson mid+1,R,rs
int sz[maxn],dep[maxn],fa[maxn],son[maxn],id[maxn],top[maxn];
int add[maxn<<2],val[maxn],arr[maxn],cnt,ptr;
struct node
{
int v;
node *next;
} ed[maxn<<1],*head[maxn];
void adde(int u,int v)
{
ed[cnt].v=v;
ed[cnt].next=head[u];
head[u]=&ed[cnt++];
}
void build(int L,int R,int rt)
{
add[rt]=0;
if(L==R)
{
add[rt]=val[L];
return;
}
int ls=rt<<1,rs=ls|1,mid=(L+R)>>1;
build(lson);
build(rson);
}
void update(int L,int R,int rt,int l,int r,int d)
{
if(l<=L&&R<=r)
{
add[rt]+=d;
return;
}
int ls=rt<<1,rs=ls|1,mid=(L+R)>>1;
if(l<=mid)
update(lson,l,r,d);
if(r>mid)
update(rson,l,r,d);
}
int qu(int L,int R,int rt,int p)
{
if(L==R)
return add[rt];
int ls=rt<<1,rs=ls|1,mid=(L+R)>>1;
if(p<=mid)
return qu(lson,p)+add[rt];
else
return qu(rson,p)+add[rt];
}
void dfs(int u)
{
int v,ms=0;
sz[u]=1,son[u]=-1;
for(node *p=head[u];p!=NULL;p=p->next)
{
v=p->v;
if(v==fa[u])
continue;
dep[v]=dep[u]+1;
fa[v]=u;
dfs(v);
if(sz[v]>ms)
ms=sz[v],son[u]=v;
sz[u]+=sz[v];
}
}
void getid(int u,int ft)
{
id[u]=++ptr,top[u]=ft;
val[ptr]=arr[u];
if(son[u]!=-1)
getid(son[u],top[u]);
for(node *p=head[u];p!=NULL;p=p->next)
{
if(p->v==son[u]||p->v==fa[u])
continue;
getid(p->v,p->v);
}
}
void init(int rt)
{
fa[rt]=-1;
dep[rt]=ptr=0;
dfs(rt);
getid(rt,rt);
}
void uppath(int u,int v,int d)
{
int f1=top[u],f2=top[v];
while(f1!=f2)
{
if(dep[f1]<dep[f2])
swap(f1,f2),swap(u,v);
update(1,ptr,1,id[f1],id[u],d);
u=fa[f1],f1=top[u];
}
if(dep[u]>dep[v])
swap(u,v);
update(1,ptr,1,id[u],id[v],d);
}
int main()
{
int n,m,p,i,u,v,w,rt;
char cmd[100];
while(~scanf("%d%d%d",&n,&m,&p))
{
for(i=1;i<=n;i++)
scanf("%d",&arr[i]);
cnt=0;
memset(head,0,sizeof head);
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
adde(u,v);
adde(v,u);
}
rt=(n+1)/2;
init(rt);
build(1,ptr,1);
while(p--)
{
scanf("%s%d",cmd,&u);
if(cmd[0]=='Q')
printf("%d\n",qu(1,ptr,1,id[u]));
else
{
scanf("%d%d",&v,&w);
if(cmd[0]=='D')
w=-w;
uppath(u,v,w);
}
}
}
return 0;
}
hdu 3966 Aragorn's Story(树链剖分对点编号)
原文地址:http://blog.csdn.net/bossup/article/details/39319567