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