HDU3966 Aragorn's Story(树链剖分 点权 模版题)
#include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <queue> #include <map> #include <set> #include <vector> #include <cstdio> using namespace std; const int N=50010; struct Edge { int to,next; }eg[N*2]; int head[N],tot,top[N],fa[N],deep[N],num[N],p[N],fp[N],son[N],pos; void init() { tot=0; memset(head,-1,sizeof(head)); pos=1; memset(son,-1,sizeof(son)); } void addedge(int u,int v) { eg[tot].to=v; eg[tot].next=head[u]; head[u]=tot++; } void dfs1(int u,int pre,int d) { deep[u]=d; fa[u]=pre; num[u]=1; for(int i=head[u];i!=-1;i=eg[i].next) { int v=eg[i].to; if(v!=pre) { dfs1(v,u,d+1); num[u]+=num[v]; if(son[u]==-1||num[v]>num[son[u]]) son[u]=v; } } } void getpos(int u,int sp) { top[u]=sp; p[u]=pos++; fp[p[u]]=u; if(son[u]==-1) return ; getpos(son[u],sp); for(int i=head[u];i!=-1;i=eg[i].next) { int v=eg[i].to; if(v!=son[u]&&v!=fa[u]) getpos(v,v); } } int lowbit(int x) { return x&(-x); } int c[N],n; int sum(int i) { int s=0; while(i>0) { s+=c[i]; i-=lowbit(i); } return s; } void add(int i,int val) { while(i<=n) { c[i]+=val; i+=lowbit(i); } } void change(int u,int v,int val) { int f1=top[u],f2=top[v],tmp=0; while(f1!=f2) { if(deep[f1]<deep[f2]) { swap(f1,f2); swap(u,v); } add(p[f1],val); add(p[u]+1,-val); u=fa[f1]; f1=top[u]; } if(deep[u]>deep[v]) swap(u,v); add(p[u],val); add(p[v]+1,-val); } int a[N]; int main() { //freopen("in.txt","r",stdin); int m,P; while(~scanf("%d%d%d",&n,&m,&P)) { int u,v,c1,c2,k; char op[10]; init(); for(int i=1;i<=n;i++) scanf("%d",&a[i]); while(m--) { scanf("%d%d",&u,&v); addedge(u,v); addedge(v,u); } dfs1(1,0,0); getpos(1,1); memset(c,0,sizeof(c)); for(int i=1;i<=n;i++) { add(p[i],a[i]); add(p[i]+1,-a[i]); } while(P--) { scanf("%s",op); if(op[0]=='Q') { scanf("%d",&u); printf("%d\n",sum(p[u])); } else { scanf("%d%d%d",&c1,&c2,&k); if(op[0]=='D') k=-k; change(c1,c2,k); } } } return 0; }