这题我建了2棵线段树,这样来处理 最值和和值,简单的题目。
#include<queue> #include<stack> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define INF 99999999 #define ll __int64 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int MAXN = 50010; struct node { int to; int v; int next; }edge[MAXN*3]; int pre[MAXN],ind,top[MAXN],fa[MAXN],son[MAXN],w[MAXN],deq[MAXN],siz[MAXN],fn; int tree1[MAXN<<2],tree2[MAXN<<2]; int n,val[MAXN]; void add(int x,int y) { edge[ind].to = y; edge[ind].next = pre[x]; pre[x] = ind++; } void dfs1(int rt,int pa,int d) { deq[rt] = d; son[rt] = 0; fa[rt] = pa; siz[rt] = 1; for(int i=pre[rt]; i!=-1; i=edge[i].next){ int t = edge[i].to; if(t != fa[rt]){ dfs1(t,rt,d+1); siz[rt] += siz[t]; if(siz[son[rt]] < siz[t]){ son[rt] = t; } } } } void dfs2(int rt,int tp) { w[rt] = ++ fn; top[rt] = tp; if(son[rt] != 0) dfs2(son[rt],tp); for(int i=pre[rt]; i!=-1; i=edge[i].next){ int t = edge[i].to; if(son[rt] != t && t != fa[rt]){ dfs2(t,t); } } } void pushup1(int rt) { tree1[rt] = max(tree1[rt<<1],tree1[rt<<1|1]); } void pushup2(int rt) { tree2[rt] = tree2[rt<<1] + tree2[rt<<1|1]; } void Insert(int p,int v,int l,int r,int rt) { if(l == r){ tree1[rt] = tree2[rt] = v; return ; } int m = (l+r)/2; if(m >= p){ Insert(p,v,lson); } else { Insert(p,v,rson); } pushup1(rt); pushup2(rt); } void updata(int p,int v,int l,int r,int rt) { if(l == r){ tree1[rt] = v; tree2[rt] = v; return ; } int m = (l+r)/2; if(m >= p){ updata(p,v,lson); } else { updata(p,v,rson); } pushup1(rt); pushup2(rt); } int query1(int L,int R,int l,int r,int rt) { if(L<=l && r<=R){ return tree1[rt]; } int m = (l+r)/2; int ans = -INF; if(m >= L){ ans = max(ans,query1(L,R,lson)); } if(m < R){ ans = max(ans,query1(L,R,rson)); } return ans; } int query2(int L,int R,int l,int r,int rt) { if(L<=l && r<=R){ return tree2[rt]; } int m = (l+r)/2; int ans = 0; if(m >= L){ ans += query2(L,R,lson); } if(m < R){ ans += query2(L,R,rson); } return ans; } int Getmax(int x,int y) { int ans = -INF; while(top[x] != top[y]) { if(deq[top[x]] < deq[top[y]]){ swap(x,y); } ans = max(ans,query1(w[top[x]],w[x],1,fn,1)); x = fa[top[x]]; } if(deq[x] < deq[y]){ swap(x,y); } ans = max(ans,query1(w[y],w[x],1,fn,1)); return ans; } int Getsum(int x,int y) { int ans = 0; while(top[x] != top[y]) { if(deq[top[x]] < deq[top[y]]){ swap(x,y); } ans += query2(w[top[x]],w[x],1,fn,1); x = fa[top[x]]; } if(deq[x] < deq[y]){ swap(x,y); } ans += query2(w[y],w[x],1,fn,1); return ans; } int main() { int i; while(~scanf("%d",&n)) { ind = 1; memset(pre,-1,sizeof(pre)); memset(tree1,0,sizeof(tree1)); memset(tree2,0,sizeof(tree2)); for(i=1; i<n; i++){ int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } for(i=1; i<=n; i++){ scanf("%d",&val[i]); } dfs1(1,1,1); fn = 0; dfs2(1,1); for(i=1; i<=n; i++){ Insert(w[i],val[i],1,fn,1); } int q; char s[10]; scanf("%d",&q); while(q--) { scanf("%s",s); int x,y; scanf("%d%d",&x,&y); if(s[0] == 'C'){ updata(w[x],y,1,fn,1); } else if(s[1] == 'S'){ printf("%d ",Getsum(x,y)); } else { printf("%d ",Getmax(x,y)); } } } }