1. 程式人生 > >luogu2590 [ZJOI2008]樹的統計

luogu2590 [ZJOI2008]樹的統計

-- names int using esp std ace print str

樹剖裸題

#include <iostream>
#include <cstdio>
using namespace std;
int n, uu, vv, hea[30005], ecnt, w[30005], ww[30005], dep[30005], cnt;
int idx[30005], son[30005], fa[30005], top[30005], q, wt[30005], siz[30005];
char ss[15];
struct Edge{
    int too, nxt;
}edge[60005];
void add_edge(int fro, int too){
    edge[++ecnt].nxt = hea[fro];
    edge[ecnt].too = too;
    hea[fro] = ecnt;
}
struct
SGT{ int sum[120005]; int zdz[120005]; void build(int o, int l, int r){ if(l==r) zdz[o] = sum[o] = wt[l]; else{ int mid=(l+r)>>1; int lson=o<<1; int rson=lson|1; zdz[lson] = zdz[rson] = -0x3f3f3f3f; if(l<=mid) build(lson, l, mid); if
(mid<r) build(rson, mid+1, r); sum[o] = sum[lson] + sum[rson]; zdz[o] = max(zdz[lson], zdz[rson]); } } void change(int o, int l, int r, int x, int k){ if(l>=x && r<=x) sum[o] = zdz[o] = k; else{ int mid=(l+r)>>1
; int lson=o<<1; int rson=lson|1; if(x<=mid) change(lson, l, mid, x, k); if(mid<x) change(rson, mid+1, r, x, k); sum[o] = sum[lson] + sum[rson]; zdz[o] = max(zdz[lson], zdz[rson]); } } int querySum(int o, int l, int r, int x, int y){ if(l>=x && r<=y) return sum[o]; else{ int mid=(l+r)>>1; int lson=o<<1; int rson=lson|1; int ans=0; if(x<=mid) ans += querySum(lson, l, mid, x, y); if(mid<y) ans += querySum(rson, mid+1, r, x, y); return ans; } } int queryZdz(int o, int l, int r, int x, int y){ if(l>=x && r<=y) return zdz[o]; else{ int mid=(l+r)>>1; int lson=o<<1; int rson=lson|1; int ans=-0x3f3f3f3f; if(x<=mid) ans = max(ans, queryZdz(lson, l, mid, x, y)); if(mid<y) ans = max(ans, queryZdz(rson, mid+1, r, x, y)); return ans; } } }sgt; void dfs1(int x, int f){ fa[x] = f; dep[x] = dep[f] + 1; siz[x] = 1; int maxSon=-1; for(int i=hea[x]; i; i=edge[i].nxt){ int t=edge[i].too; if(t==f) continue; dfs1(t, x); siz[x] += siz[t]; if(maxSon<siz[t]){ maxSon = siz[t]; son[x] = t; } } } void dfs2(int x, int topf){ top[x] = topf; idx[x] = ++cnt; wt[cnt] = w[x]; if(!son[x]) return ; dfs2(son[x], topf); for(int i=hea[x]; i; i=edge[i].nxt){ int t=edge[i].too; if(t==fa[x] || t==son[x]) continue; dfs2(t, t); } } int queryRangeSum(int uu, int vv){ int ans=0; while(top[uu]!=top[vv]){ if(dep[top[uu]]<dep[top[vv]]) swap(uu, vv); ans += sgt.querySum(1, 1, n, idx[top[uu]], idx[uu]); uu = fa[top[uu]]; } if(dep[uu]>dep[vv]) swap(uu, vv); ans += sgt.querySum(1, 1, n, idx[uu], idx[vv]); return ans; } int queryRangeZdz(int uu, int vv){ int ans=-0x3f3f3f3f; while(top[uu]!=top[vv]){ if(dep[top[uu]]<dep[top[vv]]) swap(uu, vv); ans = max(ans, sgt.queryZdz(1, 1, n, idx[top[uu]], idx[uu])); uu = fa[top[uu]]; } if(dep[uu]>dep[vv]) swap(uu, vv); ans = max(ans, sgt.queryZdz(1, 1, n, idx[uu], idx[vv])); return ans; } int main(){ cin>>n; for(int i=1; i<n; i++){ scanf("%d %d", &uu, &vv); add_edge(uu, vv); add_edge(vv, uu); } for(int i=1; i<=n; i++) scanf("%d", &w[i]); dep[1] = 1; dfs1(1, 0); dfs2(1, 1); sgt.build(1, 1, n); cin>>q; while(q--){ scanf("%s %d %d", ss, &uu, &vv); if(ss[1]==‘H‘) sgt.change(1, 1, n, idx[uu], vv); if(ss[1]==‘M‘) printf("%d\n", queryRangeZdz(uu, vv)); if(ss[1]==‘S‘) printf("%d\n", queryRangeSum(uu, vv)); } return 0; }

luogu2590 [ZJOI2008]樹的統計