首页 > 代码库 > 【BZOJ1036】【ZJOI2008】树的统计Count 树链剖分裸题
【BZOJ1036】【ZJOI2008】树的统计Count 树链剖分裸题
题解:裸的,没什么好说的。
树链剖分不会的先理解一下重链轻链,然后直接扒我代码理解就行了。
贴代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 30100 #define inf 0x3f3f3f3f using namespace std; struct KSD { int u,v,next; }e[N<<1]; int head[N],cnt; void add(int u,int v) { ++cnt; e[cnt].u=u; e[cnt].v=v; e[cnt].next=head[u]; head[u]=cnt; } int n,m; int w[N],tw[N]; struct Segment_Tree { int l,r,x[2]; }s[N<<2]; int deep[N],pos[N],fa[N],son[N],top[N]; int dfs1(int x,int p) { int i,v,sum=1,ax=-inf; deep[x]=deep[p]+1; fa[x]=p; for(i=head[x];i;i=e[i].next) { v=e[i].v; if(v==p)continue; int temp=dfs1(v,x); sum+=temp; if(ax<temp)ax=temp,son[x]=v; } return sum; } void dfs2(int x,int p,int r) { int i,v; pos[x]=++cnt; top[x]=r; if(son[x])dfs2(son[x],x,r); for(i=head[x];i;i=e[i].next) { v=e[i].v; if(v!=son[x]&&v!=p)dfs2(v,x,v); } } void pushup(int x) { s[x].x[0]=s[x<<1].x[0]+s[x<<1|1].x[0]; s[x].x[1]=max(s[x<<1].x[1],s[x<<1|1].x[1]); } void build(int note,int l,int r) { s[note].l=l,s[note].r=r; if(l==r) { s[note].x[0]=s[note].x[1]=w[l]; return ; } int mid=l+r>>1; build(note<<1,l,mid); build(note<<1|1,mid+1,r); pushup(note); } void change(int note,int x,int y) { if(s[note].l==s[note].r) { s[note].x[0]=s[note].x[1]=y; return ; } int mid=s[note].l+s[note].r>>1; if(x<=mid)change(note<<1,x,y); else change(note<<1|1,x,y); pushup(note); } int QUERY(int note,int l,int r,int c) { if(s[note].l==l&&r==s[note].r)return s[note].x[c]; int mid=s[note].l+s[note].r>>1; if(r<=mid)return QUERY(note<<1,l,r,c); else if(l>mid)return QUERY(note<<1|1,l,r,c); else { if(c==0)return QUERY(note<<1,l,mid,0)+QUERY(note<<1|1,mid+1,r,0); else return max(QUERY(note<<1,l,mid,1),QUERY(note<<1|1,mid+1,r,1)); } } int query(int a,int b,int c) { int A,B,ans[2]; ans[0]=0,ans[1]=-inf; for(A=top[a],B=top[b];A!=B;a=fa[A],A=top[a]) { if(deep[A]<deep[B])swap(A,B),swap(a,b); if(c==0)ans[0]+=QUERY(1,pos[A],pos[a],0); else ans[1]=max(ans[1],QUERY(1,pos[A],pos[a],1)); }if(deep[a]<deep[b])swap(a,b); if(c==0)return ans[0]+QUERY(1,pos[b],pos[a],0); else return max(ans[1],QUERY(1,pos[b],pos[a],1)); } char opt[10]; int main() { // freopen("test.in","r",stdin); // freopen("my.out","w",stdout); int i,a,b; scanf("%d",&n); for(i=1;i<n;i++) { scanf("%d%d",&a,&b); add(a,b); add(b,a); } cnt=0; dfs1(1,0); dfs2(1,0,1); for(i=1;i<=n;i++)scanf("%d",&tw[i]),w[pos[i]]=tw[i]; build(1,1,n); scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%s",opt); scanf("%d%d",&a,&b); if(opt[0]=='Q') { if(opt[1]=='S')printf("%d\n",query(a,b,0)); else printf("%d\n",query(a,b,1)); } else change(1,pos[a],b); } // fclose(stdin); // fclose(stdout); return 0; }
【BZOJ1036】【ZJOI2008】树的统计Count 树链剖分裸题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。