Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10483 Accepted Submission(s): 2757
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <queue> #include <vector> #define inf 2e9 #define met(a,b) memset(a,b,sizeof a) typedef long long ll; using namespace std; const int N =2e5+5; const int M = 4e6+5; int n,sum[N],m,tot,num,q; int tre[N*2],laz[N*2]; int dep[N],siz[N],fa[N],id[N],son[N],val[N],top[N],c[N]; int head[N]; struct EDG{ int to,next; }edg[N]; void add(int u,int v){ edg[tot].to=v;edg[tot].next=head[u];head[u]=tot++; } void init(){ met(head,-1);met(tre,0); met(son,0);met(laz,0); tot=0;num=0; } void dfs1(int u, int f, int d) { dep[u] = d; siz[u] = 1; son[u] = 0; fa[u] = f; for (int i =head[u]; i !=-1; i=edg[i].next) { int ff = edg[i].to; if (ff == f) continue; dfs1(ff, u, d + 1); siz[u] += siz[ff]; if (siz[son[u]] < siz[ff]) son[u] = ff; } } void dfs2(int u, int tp) { top[u] = tp; id[u] = ++num; if (son[u]) dfs2(son[u], tp); for (int i =head[u]; i !=-1; i=edg[i].next) { int ff = edg[i].to; if (ff == fa[u] || ff == son[u]) continue; dfs2(ff, ff); } } void build(int l,int r,int pos){ if(l==r){ tre[pos]=val[l]; return; } int mid=(l+r)>>1; build(l,mid,pos<<1); build(mid+1,r,pos<<1|1); return; } void pushdown(int num) { if(laz[num]!=0) { tre[num*2]+=laz[num]; tre[num*2+1]+=laz[num]; laz[num*2]+=laz[num]; laz[num*2+1]+=laz[num]; laz[num]=0; } } void update(int num,int le,int ri,int x,int y,int p) { if(x<=le&&y>=ri) { tre[num]+=p; laz[num]+=p; return ; } pushdown(num); int mid=(le+ri)/2; if(x<=mid) update(num*2,le,mid,x,y,p); if(y>mid) update(num*2+1,mid+1,ri,x,y,p); } int query(int num,int le,int ri,int x) { if(le==ri) { return tre[num]; } pushdown(num); int mid=(le+ri)/2; if(x<=mid) return query(num*2,le,mid,x); else return query(num*2+1,mid+1,ri,x); } void Youngth(int u,int v,int p){ int tp1=top[u],tp2=top[v]; while(tp1!=tp2){ if(dep[tp1]<dep[tp2]){ swap(tp1,tp2);swap(u,v); } update(1,1,num,id[tp1],id[u],p); u=fa[tp1]; tp1=top[u]; } if(dep[u]>dep[v])swap(u,v); update(1,1,num,id[u],id[v],p); } int main() { int u,v,p; while(~scanf("%d%d%d",&n,&m,&q)) { init(); for(int i=1;i<=n;i++)scanf("%d",&c[i]); while(m--){ scanf("%d%d",&u,&v); add(u,v);add(v,u); } dfs1(1,0,1); dfs2(1,1); for(int i=1;i<=n;i++){ val[id[i]]=c[i]; } build(1,num,1); char str[100]; while(q--){ scanf("%s",str); if(str[0]==‘I‘){ scanf("%d%d%d",&u,&v,&p); Youngth(u,v,p); } else if(str[0]==‘D‘){ scanf("%d%d%d",&u,&v,&p); Youngth(u,v,-p); } else { scanf("%d",&u); printf("%d\n",query(1,1,num,id[u])); } } } return 0; }
HDU 3966 Aragorn's Story(树链剖分)(线段树区间修改)
原文:http://www.cnblogs.com/jianrenfang/p/6357485.html