bzoj1036: [ZJOI2008]树的统计Count 树链剖分模板
无脑码代码....
#include<bits/stdc++.h> using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); } while(ch<='9'&&ch>='0') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } void put(int x){ if(x==0){ putchar('0'); putchar('\n'); return; } if(x<0){ putchar('-'); x=-x; } int num=0;char ch[16]; while(x) ch[++num]=x%10+'0',x/=10; while(num) putchar(ch[num--]); putchar('\n'); } struct one { int y,next; }; one e[60100]; struct ppp { int l,r,val,maxn; }; ppp tree[130000]; char s[20]; int maxn=1000000000,maxn2=-1000000000,a[30010],w[30010],n,m,fa[30010],d[30010],sizer[30010],top[30010],lin[30010],len=0,din[30010],dout[30010],wson[30010],cnt=0; /*void dfs1(int x,int f) { int y; fa[x]=f; wson[x]=0;//the heaviest son sizer[x]=1; for (int i=lin[x];i;i=e[i].next) if (e[i].y!=f) { y=e[i].y; d[y]=d[x]+1; dfs1(y,x); sizer[x]+=sizer[y]; if (sizer[wson[x]]<sizer[y]) wson[x]=y; } } */ void dfs1(int p,int f) { int y; fa[p]=f; wson[p]=0; sizer[p]=1; for(int i=lin[p];i;i=e[i].next) { int maxnx2=0,ww=0; if(e[i].y!=f) { y=e[i].y; d[y]=d[p]+1; dfs1(y,p); sizer[p]+=sizer[y]; /*if(sizer[y]>maxnx2) { maxnx2=sizer[y]; wson[p]=y; }*/ if (sizer[wson[p]]<sizer[y]) wson[p]=y; } } } void dfs2(int p) { din[p]=++cnt; w[cnt]=a[p]; if(!top[p])top[p]=p; if(wson[p]) { top[wson[p]]=top[p]; dfs2(wson[p]); } for(int i=lin[p];i;i=e[i].next) { if(fa[p]==e[i].y||e[i].y==wson[p])continue; dfs2(e[i].y); } //dout[p]=cnt; } void insert(int x,int y) { e[++len].next=lin[x]; lin[x]=len; e[len].y=y; } void maketree(int l,int r,int id) { tree[id].l=l;tree[id].r=r; if(l>=r) { tree[id].maxn=w[l]; tree[id].val=w[l]; return; } int mid=(l+r)>>1; maketree(l,mid,id<<1); maketree(mid+1,r,id<<1|1); tree[id].maxn=max(tree[id<<1].maxn,tree[id<<1|1].maxn); tree[id].val=tree[id<<1].val+tree[id<<1|1].val; } /*void chag(int l,int val,int id) { if(l<tree[id].l||l>tree[id].r)return; if(tree[id].l==tree[id].r){tree[id].maxn=val;tree[id].val=val;return;} int mid=(tree[id].l+tree[id].r)>>1; if(l<=mid)chag(l,val,id<<1); else chag(l,val,id<<1|1); tree[id].maxn=max(tree[id<<1].maxn,tree[id<<1|1].maxn); tree[id].val=tree[id<<1].val+tree[id<<1|1].val; }*/ void updata(int p) { tree[p].val=tree[p<<1].val+tree[p<<1|1].val; tree[p].maxn=max(tree[p<<1].maxn,tree[p<<1|1].maxn); } void chag(int x,int y,int p) { if (tree[p].l==x && tree[p].r==x) { tree[p].val=tree[p].maxn=y; return ; } int mid=(tree[p].l+tree[p].r) >> 1; if (x<=mid) chag(x, y,p<<1); if (x>mid) chag(x, y,p<<1|1); updata(p); } /*int putit2(int l,int r,int id) { if(tree[id].r<l||r<tree[id].l)return -maxn; if(tree[id].r<=r&&tree[id].l>=l)return tree[id].maxn; int a1=putit2(l,r,id<<1); int a2=putit2(l,r,id<<1|1); a1=max(a1,a2); return a1; }*/ int putit2(int l,int r,int p) { if (tree[p].l==l && tree[p].r==r) return tree[p].maxn; int mid=(tree[p].l+tree[p].r) >> 1; if (r<=mid) return putit2(l, r,p<<1); if (l>mid) return putit2(l, r,p<<1|1); if (l<=mid && r>mid) { int s1=putit2(l, mid,p<<1); int s2=putit2(mid+1, r,p<<1|1); return max(s1,s2); } } void putit1(int x,int y) { int ans=-maxn; while(top[x]!=top[y]) { if(d[top[x]]<d[top[y]]) { ans=max(ans,putit2(din[top[y]],din[y],1)); y=fa[top[y]]; } else { ans=max(ans,putit2(din[top[x]],din[x],1)); x=fa[top[x]]; } } if(d[x]<d[y])ans=max(ans,putit2(din[x],din[y],1)); else ans=max(ans,putit2(din[y],din[x],1)); put(ans); } /*int putsum2(int l,int r,int id) { if(tree[id].r<l||r<tree[id].l)return 0; if(tree[id].r<=r&&tree[id].l>=l)return tree[id].val; int mid=(tree[id].r+tree[id].l)>>1; if(l>=mid) int a1=putsum2(l,r,id<<1); int a2=putsum2(l,r,id<<1|1); return a1+a2; }*/ int putsum2(int l,int r,int p) { if (tree[p].l==l && tree[p].r==r) return tree[p].val; int mid=(tree[p].l+tree[p].r) >> 1; if (r<=mid) return putsum2(l, r,p<<1); if (l>mid) return putsum2( l, r,p<<1|1); if (l<=mid && r>mid) { int s1=putsum2(l, mid,p<<1); int s2=putsum2(mid+1, r,p<<1|1); return s1+s2; } } void putsum1(int x,int y) { int ans=0; while(top[x]!=top[y]) { if(d[top[x]]<d[top[y]]) { ans+=putsum2(din[top[y]],din[y],1); y=fa[top[y]]; } else { ans+=putsum2(din[top[x]],din[x],1); x=fa[top[x]]; } } if(d[x]==d[y]) { ans+=putsum2(din[x],din[x],1); } else if(d[x]<d[y]) { ans+=putsum2(din[x],din[y],1); } else { ans+=putsum2(din[y],din[x],1); } //printf("%d\n",ans); put(ans); } int main() { //freopen("xf.in","r",stdin); //freopen("xf.out","w",stdout); n=read(); int aa,bb; for(int i=1;i<n;i++) { aa=read();bb=read(); insert(aa,bb);insert(bb,aa); } for(int i=1;i<=n;i++)a[i]=read(); d[1]=1; //dfs1(1);dfs2(1); dfs1(1,0); dfs2(1); maketree(1,n,1); scanf("%d",&m); int x,y; for(int i=1;i<=m;i++) { scanf("%s",s); x=read();y=read(); if(s[0]=='C')chag(din[x],y,1); else if(s[1]=='M')putit1(x,y); else putsum1(x,y); } return 0; }