剖分+线段树区间更新+单点查询
树链剖分入门题
#include <bits/stdc++.h> #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 using namespace std; const int maxn = 100000+10; int num[maxn]; int n , m , Q; //树链剖分 int siz[maxn], top[maxn], son[maxn]; int dep[maxn], fa[maxn], tid[maxn], seg_pos[maxn]; int tim; vector<int>es[maxn]; void Init() { for(int i = 0 ; i < maxn ; i++) { es[i].clear(); } tim = 0; memset(son, -1, sizeof(son)); } void DFS1(int now, int from, int deep) // 寻找重边 { dep[now] = deep; fa[now] = from; siz[now] = 1; int length = es[now].size(); for(int i = 0 ; i < length ; i++) { int v = es[now][i]; if(v != from) { DFS1(v, now, deep + 1); siz[now] += siz[v]; if(son[now] == -1 || siz[v] > siz[son[now]]) { son[now] = v; } } } } void DFS2(int now, int tp) // 重边链接成重链 { top[now] = tp; tid[now] = ++tim; // now 在 线段树 上的编号 seg_pos[tid[now]] = now; if(son[now] == -1) return; DFS2(son[now],tp); int length = es[now].size(); for(int i = 0 ; i < length ; i++) { int v = es[now][i]; if(v != son[now] && v != fa[now]) DFS2(v,v); } } //线段树 int sum[4*maxn],col[4*maxn]; void PushUP(int rt) { sum[rt]=max(sum[rt<<1],sum[rt<<1|1]); } void PushDown(int rt,int m) { if(col[rt]) { col[rt<<1]+=col[rt]; col[rt<<1|1]+=col[rt]; sum[rt<<1]+=(m-(m>>1))*col[rt]; sum[rt<<1|1]+=(m>>1)*col[rt]; col[rt]=0; } } void Build(int l,int r,int rt) { col[rt]=0; if(l==r) { sum[rt]=num[seg_pos[l]]; return; } int mid=(l+r)>>1; Build(lson); Build(rson); PushUP(rt); } void Update(int L,int R,int v,int l,int r,int rt) { if(L<=l&&R>=r) { col[rt]+=v; sum[rt]+=v*(r-l+1); return; } PushDown(rt,r-l+1); int mid=(l+r)>>1; if(L<=mid) Update(L,R,v,lson); if(R>mid) Update(L,R,v,rson); PushUP(rt); } int Query(int l,int r,int rt,int val) { if(l==r) return sum[rt]; PushDown(rt,r-l+1); int mid=(l+r)>>1; int ret=0; if(val<=mid) ret=Query(lson,val); else ret=Query(rson,val); PushUP(rt); return ret; } void Change(int x, int y, int val) { while(top[x] != top[y]) { if(dep[top[x]] < dep[top[y]]) swap(x,y); Update(tid[top[x]], tid[x], val, 1, n, 1); x = fa[top[x]]; } if(dep[x] < dep[y]) swap(x,y); Update(tid[y], tid[x], val, 1, n, 1); } int main() { ios::sync_with_stdio(false); char type; int a,b,c; while(cin >> n >> m >> Q) { Init(); for(int i=1; i<=n; i++) cin >> num[i]; for(int i=1; i<=m; i++) { cin >> a >> b; es[a].push_back(b); es[b].push_back(a); } DFS1(1,0,0); DFS2(1,1); Build(1,n,1); while(Q--) { cin >> type; if(type=='Q') { cin >> a; cout << Query(1,n,1,tid[a]) << endl; } else { cin >> a >> b >> c; if(type=='D') c=-c; Change(a,b,c); } } } return 0; }