1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<stdio.h> 3 #include<string.h> 4 int now,cnt,n,a[50005]; 5 int next[100005],head[50005],point[100005]; 6 int num[50005],father[50005],son[50005],deep[50005]; 7 int top[50005],tree[50005],pre[50005]; 8 int seg[200005],setv[200005]; 9 void add(int x,int y) 10 { 11 next[++now]=head[x]; 12 head[x]=now; 13 point[now]=y; 14 } 15 void dfs1(int u) 16 { 17 num[u]=1; //节点儿子数(包括自己) 18 for (int i=head[u];i!=-1;i=next[i]) 19 { 20 int v=point[i]; 21 if (v!=father[u]){ 22 father[v]=u; //父亲节点 23 deep[v]=deep[u]+1;//节点深度 24 dfs1(v); 25 num[u]+=num[v];//讲v dfs完之后再加上num 26 if (son[u]==-1||num[v]>num[son[u]]) son[u]=v; //儿子节点中num最多的为重链,son为重儿子 27 } 28 } 29 } 30 void dfs2(int u,int lead) 31 { 32 top[u]=lead; //进来的点都是重链上的点,top为该点的重链根 33 tree[u]=++cnt;//重链上的点映射到线段树上编号 34 pre[cnt]=u;//线段树上的点到原树上的点编号,为了建树 35 if (son[u]==-1) return; 36 dfs2(son[u],lead); //先把该条树上重链走完,再线段树上才能是连续的 37 for (int i=head[u];i!=-1;i=next[i]) 38 { 39 int v=point[i];//走一步轻链 40 if (father[u]!=v&&son[u]!=v) dfs2(v,v); 41 } 42 } 43 44 void build(int o,int l,int r) 45 { 46 seg[o]=0; setv[o]=0; 47 if (l==r) { 48 seg[o]=a[pre[l]]; 49 return; 50 } 51 int mid=l+(r-l)/2; 52 build(o*2,l,mid); 53 build(o*2+1,mid+1,r); 54 } 55 void update(int o,int l,int r,int y1,int y2,int d) 56 { 57 if (y1<=l&&y2>=r) 58 { 59 setv[o]+=d; 60 return; 61 } 62 if (setv[o]!=0) //pushdown 63 { 64 setv[o*2]+=setv[o]; 65 setv[o*2+1]+=setv[o]; 66 setv[o]=0; 67 } 68 int mid=l+(r-l)/2; 69 if (y1<=mid) update(o*2,l,mid,y1,y2,d); 70 if (y2>mid) update(o*2+1,mid+1,r,y1,y2,d); 71 } 72 int query(int o,int l,int r,int y) 73 { 74 if (l==r) return seg[o]+setv[o]; 75 if (setv[o]!=0) //pushdown 76 { 77 setv[o*2]+=setv[o]; 78 setv[o*2+1]+=setv[o]; 79 setv[o]=0; 80 } 81 int mid=l+(r-l)/2; 82 if (y<=mid) return query(o*2,l,mid,y); 83 return query(o*2+1,mid+1,r,y); 84 } 85 86 void change(int l,int r,int d)//连接树与线段树核心 87 { 88 int temp; 89 while (top[l]!=top[r]) //直到在一条重链上 90 { 91 if (deep[top[l]]<deep[top[r]]) {temp=l; l=r; r=temp; }//先处理更深重链 92 update(1,1,n,tree[top[l]],tree[l],d);//核心! 93 l=father[top[l]]; 94 } 95 if (deep[l]>deep[r]) {temp=l; l=r; r=temp; } 96 update(1,1,n,tree[l],tree[r],d); 97 } 98 int main() 99 { 100 int m,q,i,x,y,d; 101 char s[5]; 102 while (~scanf("%d%d%d",&n,&m,&q)) 103 { 104 now=0; cnt=0; 105 deep[1]=1; father[1]=1; 106 memset(son,-1,sizeof(son)); 107 memset(head,-1,sizeof(head)); 108 for (i=1;i<=n;i++) scanf("%d",&a[i]); 109 for (i=1;i<=m;i++) 110 { 111 scanf("%d%d",&x,&y); 112 add(x,y); add(y,x); 113 } 114 dfs1(1); dfs2(1,1); 115 build(1,1,n); 116 for (i=1;i<=q;i++) 117 { 118 scanf("%s",&s); 119 if (s[0]=='Q') { 120 scanf("%d",&x); 121 printf("%d\n",query(1,1,n,tree[x])); 122 } 123 else{ 124 scanf("%d%d%d",&x,&y,&d); 125 if (s[0]=='D') d=-d; 126 change(x,y,d); 127 } 128 } 129 } 130 return 0; 131 }
转载于:https://www.cnblogs.com/xiao-xin/articles/4003282.html