BZOJ 3531 [SDOI2014]旅行 树链剖分+线段树
2016-12-11 15:59
429 查看
题目大意:给定一棵节点为n的树,每个节点有一个颜色c(c<=n)和权值(正整数)。实现以下操作:
1.修改某个点的颜色
2.修改某个点的权值
3.询问两点间与这两个点同颜色的最大值
4.询问两点间与这两个点同颜色的和
保证询问的两点同色
挺简单的一道树链剖分+线段树。给每个颜色开一个线段树,不过要动态开内存。空间复杂度O(nlogn)。
树链剖分一定要注意最后x,y两点在同一链上时也要统计答案。
1.修改某个点的颜色
2.修改某个点的权值
3.询问两点间与这两个点同颜色的最大值
4.询问两点间与这两个点同颜色的和
保证询问的两点同色
挺简单的一道树链剖分+线段树。给每个颜色开一个线段树,不过要动态开内存。空间复杂度O(nlogn)。
树链剖分一定要注意最后x,y两点在同一链上时也要统计答案。
#include <cstdio> #include <cstring> #define N 100005 #define Max(a,b) (a>b?a:b) using namespace std; inline void Swap(int& x,int& y){int z=x;x=y;y=z;} struct Segment_Tree{ Segment_Tree *ls,*rs; int l,r,sum,maxx; void maintain(){ sum=maxx=0; if(ls!=NULL){ sum+=ls->sum; maxx=Max(maxx,ls->maxx); } if(rs!=NULL){ sum+=rs->sum; maxx=Max(maxx,rs->maxx); } } Segment_Tree(int l,int r):l(l),r(r){ls=rs=NULL; sum=maxx=0;} }*ST ; typedef Segment_Tree S_T; struct Edge{ int to,nex; bool vis; }e[N<<1]; int n,m,T,fir ,seq ; struct Point{ int Size,dep,pos,top,fa,son,val,belief; }p ; void dfs1(int x){ p[x].Size=1; for(int i=fir[x];i!=-1;i=e[i].nex){ if(!e[i].vis) continue; int to=e[i].to; p[to].dep=p[x].dep+1; p[to].fa=x; e[i^1].vis=false; dfs1(to); p[x].Size+=p[to].Size; if(p[p[x].son].Size<p[to].Size) p[x].son=to; } return ; } void dfs2(int x){ T++; p[x].pos=T; if(p[p[x].fa].son==x) p[x].top=p[p[x].fa].top; else p[x].top=x; if(p[x].son) dfs2(p[x].son); for(int i=fir[x];i!=-1;i=e[i].nex){ if(e[i].to==p[x].son || e[i].to==p[x].fa) continue; dfs2(e[i].to); } return ; } void Insert(S_T*& x,int l,int r,int pos,int v){ if(x==NULL) x=new S_T(l,r); if(l==pos && r==pos){ x->sum=x->maxx=v; return ; } int mid=(l+r)>>1; if(pos<=mid) Insert(x->ls,l,mid,pos,v); else Insert(x->rs,mid+1,r,pos,v); x->maintain(); return ; } void Delete(S_T*& x,int pos){ if(x->l==pos && x->r==pos) { delete x; x=NULL; return ; } int mid=(x->l+x->r)>>1; if(pos<=mid) Delete(x->ls,pos); else Delete(x->rs,pos); if(x->ls==NULL && x->rs==NULL){ delete x; x=NULL; } else x->maintain(); return ; } int Query_Max(S_T* x,int l,int r){ if(x==NULL) return 0; if(x->l==l && x->r==r) return x->maxx; int mid=(x->l+x->r)>>1; if(r<=mid) return Query_Max(x->ls,l,r); if(l>mid) return Query_Max(x->rs,l,r); return Max(Query_Max(x->ls,l,mid),Query_Max(x->rs,mid+1,r)); } int Query_Sum(S_T* x,int l,int r){ if(x==NULL) return 0; if(x->l==l && x->r==r) return x->sum; int mid=(x->l+x->r)>>1; if(r<=mid) return Query_Sum(x->ls,l,r); if(l>mid) return Query_Sum(x->rs,l,r); return Query_Sum(x->ls,l,mid)+Query_Sum(x->rs,mid+1,r); } int main(){ memset(fir,-1,sizeof fir); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&p[i].val,&p[i].belief); for(int i=0;i<n-1;i++) { int x,y,u=i<<1; scanf("%d%d",&x,&y); e[u].to=y; e[u].nex=fir[x]; fir[x]=u; e[u].vis=true; u^=1; e[u].to=x; e[u].nex=fir[y]; fir[y]=u; e[u].vis=true; } p[1].dep=1; p[1].top=1; dfs1(1); dfs2(1); for(int i=1;i<=n;i++) Insert(ST[p[i].belief],1,n,p[i].pos,p[i].val); while(m--){ int x,y; char mode[5]; scanf("%s%d%d",mode,&x,&y); if(mode[1]=='C'){//Change_Belief Delete(ST[p[x].belief],p[x].pos); p[x].belief=y; Insert(ST[y],1,n,p[x].pos,p[x].val); } else if(mode[1]=='W'){//Change_Value p[x].val=y; Insert(ST[p[x].belief],1,n,p[x].pos,y); } else if(mode[1]=='S'){//Query_Sum int ans=0,b=p[x].belief; while(p[x].top!=p[y].top){ int topx=p[x].top,topy=p[y].top; if(p[topx].dep<p[topy].dep) Swap(x,y) , Swap(topx,topy); ans+=Query_Sum(ST[b],p[topx].pos,p[x].pos); x=p[topx].fa; } if(p[x].dep<p[y].dep) Swap(x,y); ans+=Query_Sum(ST[b],p[y].pos,p[x].pos); printf("%d\n",ans); } else if(mode[1]=='M'){//Query_Max int ans=0,b=p[x].belief; while(p[x].top!=p[y].top){ int topx=p[x].top,topy=p[y].top; if(p[topx].dep<p[topy].dep) Swap(x,y) , Swap(topx,topy); ans=Max(ans,Query_Max(ST[b],p[topx].pos,p[x].pos)); x=p[topx].fa; } if(p[x].dep<p[y].dep) Swap(x,y); ans=Max(ans,Query_Max(ST[b],p[y].pos,p[x].pos)); printf("%d\n",ans); } } return 0; }
相关文章推荐
- BZOJ 3531: [Sdoi2014]旅行
- 【bzoj3531】[SDOI2014]旅行
- 3531: [Sdoi2014]旅行 (树链剖分+线段树)
- bzoj 3531: [Sdoi2014]旅行 树链剖分
- [bzoj3531][Sdoi2014]旅行
- [BZOJ3531][SDOI2014]旅行(树剖+线段树)
- [BZOJ3531][SDOI2014]旅行(链剖+线段树动态开点)
- 【块状树】【树链剖分】【线段树】bzoj3531 [Sdoi2014]旅行
- BZOJ 3531 [Sdoi2014]旅行 树链剖分
- [BZOJ3531] [SDOI2014] 旅行
- 【BZOJ3531】【Sdoi2014】旅行 树链剖分。
- bzoj3531[Sdoi2014]旅行(树剖)
- BZOJ 3531 SDOI2014 旅行 树链剖分
- bzoj3531 [Sdoi2014]旅行
- bzoj 3531 [Sdoi2014]旅行(树链剖分,线段树)
- |BZOJ 3531|树链剖分|动态开点线段树|[Sdoi2014]旅行
- 【bzoj3531】 [SDOI2014]旅行 树链剖分+动态开点线段树
- [bzoj3531][Sdoi2014][旅行] (主席树+树链剖分)
- 【BZOJ3531】【SDOI2014】旅行
- 【BZOJ 3531】 [Sdoi2014]旅行