分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

【BZOJ 1146】[CTSC2008]网络管理Network

发布时间:2023-09-06 01:30责任编辑:赖小花关键词:暂无标签

树剖+树状数组套线段树O(nlogn^3)(我打的),有一种更加优秀的算法是O(nlogn^2)的就是直接树状数组套线段树欧拉序(并不快),或者是用主席树维护原始的树的信息,同时用树状数组套线段树维护dfs序上的修改(很优秀),这道题将树上信息转化为序列信息,并在此基础之上用任意树套树,只不过转化的方式不一样,要么是树剖,要么是树上差分(dfs序或者欧拉序都可以)

#include <cstdio>#include <cstring>#include <algorithm>#define mid ((l+r)>>1)#define newnode (node+(sz++))const int N=80010;const int Inf=99999999;char xB[(1<<15)+10],*xS=xB,*xTT=xB;#define gtc() (xS==xTT&&(xTT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xTT)?0:*xS++)inline void read(int &sum){ ???register char ch=gtc(); ???for(sum=0;ch<‘0‘||ch>‘9‘;ch=gtc()); ???for(;ch>=‘0‘&&ch<=‘9‘;sum=(sum<<1)+(sum<<3)+ch-‘0‘,ch=gtc());}struct Segment_Tree{ ?Segment_Tree *ch[2]; ?int size;}node[N*150],*add[N],*red[N],*null,*root[N];int cnt1,cnt2;int n,cnt;int val[N];struct V{ ?int to,next;}c[N<<1];int head[N],t,sz;int ote[N],weight[N],deep[N],size[N];int Ti,top[N],dfn[N],id[N];inline void Init(){ ?null=newnode; ?null->ch[0]=null->ch[1]=null; ?null->size=0; ?for(int i=1;i<=n;++i)root[i]=null;}inline void U1(Segment_Tree *&p,int l,int r,int pos){ ?--p->size; ?if(l==r)return; ?if(pos<=mid)U1(p->ch[0],l,mid,pos); ?else U1(p->ch[1],mid+1,r,pos);}inline void U2(Segment_Tree *&p,int l,int r,int pos){ ?if(p==null)p=newnode,p->ch[0]=p->ch[1]=null,p->size=0; ?++p->size; ?if(l==r)return; ?if(pos<=mid)U2(p->ch[0],l,mid,pos); ?else U2(p->ch[1],mid+1,r,pos);}inline int Q(int l,int r,int k){ ?if(l==r)return l; ?register int sum=0,i; ?for(i=1;i<=cnt1;++i) ???sum+=add[i]->ch[1]->size; ?for(i=1;i<=cnt2;++i) ???sum-=red[i]->ch[1]->size; ?if(sum>=k){ ???for(i=1;i<=cnt1;++i) ?????add[i]=add[i]->ch[1]; ???for(i=1;i<=cnt2;++i) ?????red[i]=red[i]->ch[1]; ???return Q(mid+1,r,k); ?}else{ ???for(i=1;i<=cnt1;++i) ?????add[i]=add[i]->ch[0]; ???for(i=1;i<=cnt2;++i) ?????red[i]=red[i]->ch[0]; ???return Q(l,mid,k-sum); ?}}inline void Q1(int pos){ ?for(;pos>0;pos-=pos&(-pos)) ???add[++cnt1]=root[pos],cnt+=root[pos]->size;}inline void Q2(int pos){ ?for(;pos>0;pos-=pos&(-pos)) ???red[++cnt2]=root[pos],cnt-=root[pos]->size;}inline void U(int pos,int val0,int val){ ?for(;pos<=n;pos+=pos&(-pos)) ???U1(root[pos],0,Inf,val0),U2(root[pos],0,Inf,val);}inline void U(int pos,int val){ ?for(;pos<=n;pos+=pos&(-pos)) ???U2(root[pos],0,Inf,val);}inline void addedge(int x,int y){ ?c[++t].to=y,c[t].next=head[x],head[x]=t;}inline void dfs1(int x,int OPai){ ?ote[x]=OPai,deep[x]=deep[OPai]+1; ?size[x]=1; ?for(int i=head[x];i;i=c[i].next) ???if(c[i].to!=OPai){ ?????dfs1(c[i].to,x); ?????size[x]+=size[c[i].to]; ?????if(size[c[i].to]>size[weight[x]]) ???????weight[x]=c[i].to; ???}}inline void dfs2(int x,int tp){ ?dfn[x]=++Ti,id[Ti]=x,top[x]=tp; ?if(weight[x]==0)return; ?dfs2(weight[x],tp); ?for(int i=head[x];i;i=c[i].next) ???if(c[i].to!=ote[x]&&c[i].to!=weight[x]) ?????dfs2(c[i].to,c[i].to);}inline void Q(int x,int y){ ?while(top[x]!=top[y]){ ???if(deep[top[x]]<deep[top[y]])std::swap(x,y); ???Q1(dfn[x]),Q2(dfn[top[x]]-1); ???x=ote[top[x]]; ?} ?if(deep[x]<deep[y])std::swap(x,y); ?Q1(dfn[x]),Q2(dfn[y]-1);}int main(){ ?int T; ?read(n),read(T),Init(); ?for(int i=1;i<=n;++i)read(val[i]); ?for(int i=1,x,y;i<n;++i){ ???read(x),read(y); ???addedge(x,y),addedge(y,x); ?} ?dfs1(1,0),dfs2(1,1); ?for(int i=1;i<=n;++i) ???U(dfn[i],val[i]); ?int k,a,b; ?while(T--){ ???read(k),read(a),read(b); ???if(k==0){ ?????U(dfn[a],val[a],b),val[a]=b; ?????continue; ???} ???cnt1=cnt2=0; ???cnt=0,Q(a,b); ???if(cnt<k){ ?????puts("invalid request!"); ?????continue; ???} ???printf("%d\n",Q(0,Inf,k)); ?}return 0;}

【BZOJ 1146】[CTSC2008]网络管理Network

原文地址:http://www.cnblogs.com/TSHugh/p/8029911.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved