bzoj1036 zjoi2008 树的统计 count
填坑= =第一道裸树剖
#include<cstdio> #include<algorithm> #include<cstring> #include<cstdlib> #include<cmath> #include<vector> using namespace std; const int Maxn=30010,Maxm=30010,INF=~0u>>1; int n; struct Data{ int sum,max; Data (int sum=0,int max=-INF):sum(sum),max(max){} Data operator + (const Data& rhs)const{ return Data(sum+rhs.sum,std::max(max,rhs.max)); } }; struct SegmentTree{ Data da[Maxn*4]; int lft,rgt,w; void pp(int l,int r=0){ lft=l;rgt=r; } void change(int s,int l,int r){ if(l==r && l==lft){ da[s]=Data(w,w); return; } int mid=(l+r)>>1; if(lft<=mid) change(s<<1,l,mid); else change(s<<1|1,mid+1,r); da[s]=da[s<<1]+da[s<<1|1]; } Data query(int s,int l,int r){ if(lft<=l && r<=rgt) return da[s]; int mid=(l+r)>>1; if(rgt<=mid) return query(s<<1,l,mid); if(mid<lft) return query(s<<1|1,mid+1,r); return query(s<<1,l,mid) + query(s<<1|1,mid+1,r); } }seg; int en[Maxm*2],next[Maxm*2],fir[Maxn],tot; void Add(int from,int to){ en[++tot] = to; next[tot] = fir[from]; fir[from] = tot; } int sz[Maxn],fa[Maxn],son[Maxn],dep[Maxn]; void dfs(int u){ sz[u]=1; son[u]=0; for(int k=fir[u];k;k=next[k]){ int v=en[k]; if(v == fa[u]) continue; fa[v] = u; dep[v]=dep[u]+1; dfs(v); sz[u]+=sz[v]; if(sz[v]>sz[son[u]]) son[u] = v; } } int pos[Maxn],top[Maxn],tm; void build(int u,int pre){ top[u]=pre; pos[u]=++tm; if(son[u]) build(son[u],pre); for(int k=fir[u];k;k=next[k]){ int v=en[k]; if(v==fa[u] || v==son[u]) continue; build(v,v); } } Data query(int a,int b){ int ta=top[a],tb=top[b]; Data ret; for(;ta!=tb;a=fa[ta],ta=top[a]){ if(dep[ta]<dep[tb]) swap(a,b), swap(ta,tb); seg.pp(pos[ta],pos[a]); ret=ret+seg.query(1,1,n); } if(dep[a]>dep[b]) swap(a,b); seg.pp(pos[a],pos[b]); return ret+seg.query(1,1,n); } int main(){ #ifdef DEBUG freopen("in.txt","r",stdin); freopen("my.out","w",stdout); #endif scanf("%d",&n); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); Add(u,v); Add(v,u); } dfs(1); build(1,1); for(int i=1;i<=n;i++){ seg.pp(pos[i]); scanf("%d",&seg.w); seg.change(1,1,n); } int m; scanf("%d",&m); char cmd[10]; int a,b; for(;m--;){ scanf("%s%d%d",cmd,&a,&b); if(cmd[0]=='C') seg.lft=pos[a],seg.w=b,seg.change(1,1,n); else if(cmd[1]=='S') printf("%d\n",query(a,b).sum); else printf("%d\n",query(a,b).max); } return 0; }
原文出处http://www.cnblogs.com/showson/