BZOJ - 1036 树的统计Count (树链剖分+线段树)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=3e4+10,inf=0x3f3f3f3f; 5 int hd[N],ne,n,k,fa[N],son[N],siz[N],dep[N],top[N],dfn[N],rnk[N],tot,a[N],sum[N<<2],mx[N<<2]; 6 struct E {int v,nxt;} e[N<<1]; 7 void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;} 8 void dfs1(int u,int f,int d) { 9 fa[u]=f,son[u]=0,siz[u]=1,dep[u]=d; 10 for(int i=hd[u]; ~i; i=e[i].nxt) { 11 int v=e[i].v; 12 if(v==fa[u])continue; 13 dfs1(v,u,d+1),siz[u]+=siz[v]; 14 if(siz[v]>siz[son[u]])son[u]=v; 15 } 16 } 17 void dfs2(int u,int tp) { 18 top[u]=tp,dfn[u]=++tot,rnk[dfn[u]]=u; 19 if(!son[u])return; 20 dfs2(son[u],top[u]); 21 for(int i=hd[u]; ~i; i=e[i].nxt) { 22 int v=e[i].v; 23 if(v==fa[u]||v==son[u])continue; 24 dfs2(v,v); 25 } 26 } 27 #define ls u<<1 28 #define rs u<<1|1 29 void pu(int u) {sum[u]=sum[ls]+sum[rs],mx[u]=max(mx[ls],mx[rs]);} 30 void build(int u=1,int l=1,int r=tot) { 31 if(l==r) {sum[u]=mx[u]=a[l]; return;} 32 int mid=(l+r)>>1; 33 build(ls,l,mid),build(rs,mid+1,r); 34 pu(u); 35 } 36 void upd(int p,int x,int u=1,int l=1,int r=tot) { 37 if(l==r) {sum[u]=mx[u]=x; return;} 38 int mid=(l+r)>>1; 39 p<=mid?upd(p,x,ls,l,mid):upd(p,x,rs,mid+1,r); 40 pu(u); 41 } 42 void qry(int L,int R,int& _sum,int& _mx,int u=1,int l=1,int r=tot) { 43 if(l>=L&&r<=R) {_sum+=sum[u],_mx=max(_mx,mx[u]); return;} 44 if(l>R||r<L)return; 45 int mid=(l+r)>>1; 46 qry(L,R,_sum,_mx,ls,l,mid),qry(L,R,_sum,_mx,rs,mid+1,r); 47 } 48 void change(int u,int x) {upd(dfn[u],x);} 49 void ask(int u,int v,int& _sum,int& _mx) { 50 _sum=0,_mx=~inf; 51 for(; top[u]!=top[v]; u=fa[top[u]]) { 52 if(dep[top[u]]<dep[top[v]])swap(u,v); 53 qry(dfn[top[u]],dfn[u],_sum,_mx); 54 } 55 if(dep[u]<dep[v])swap(u,v); 56 qry(dfn[v],dfn[u],_sum,_mx); 57 } 58 int main() { 59 memset(hd,-1,sizeof hd),ne=0; 60 scanf("%d",&n); 61 for(int i=1; i<n; ++i) { 62 int u,v; 63 scanf("%d%d",&u,&v); 64 addedge(u,v); 65 addedge(v,u); 66 } 67 tot=0,dfs1(1,0,0),dfs2(1,1); 68 for(int i=1; i<=n; ++i)scanf("%d",&a[dfn[i]]); 69 build(); 70 char s[10]; 71 scanf("%d",&k); 72 while(k--) { 73 int a,b; 74 scanf("%s%d%d",s,&a,&b); 75 if(s[1]=='H')change(a,b); 76 else { 77 int _sum,_mx; 78 ask(a,b,_sum,_mx); 79 if(s[1]=='S')printf("%d\n",_sum); 80 else printf("%d\n",_mx); 81 } 82 } 83 return 0; 84 }