首页 > 代码库 > BZOJ 1984 月下“毛景树” 树链剖分
BZOJ 1984 月下“毛景树” 树链剖分
题目大意:给定一棵树,边上有边权,提供一堆乱七八糟的操作(0.0),多次询问两点之间边权最大值
将每条边的边权放在边下面的点上,然后按照点权处理就行了。注意两个点的LCA的点权不能被算进路径中去
尼玛UBUNTU奇葩系统……我不写返回值居然直接把re给我返回回去了 然后咋拍都过…… 交上去就WA…… 我跪了
再也不敢不写-Wall了……
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 100100 using namespace std; struct Segtree{ Segtree *ls,*rs; int change_mark,add_mark,max_num; void Add(int x); void Change(int x); void* operator new(size_t size); }*tree,mempool[M<<1],*C=mempool; struct abcd{ int to,f,next; }table[M<<1]; int head[M],tot=1; int n; int fa[M],son[M],dpt[M],size[M]; int pos[M],top[M],f[M],posf[M],cnt; void Segtree :: Add(int x) { add_mark+=x; max_num+=x; } void Segtree :: Change(int x) { add_mark=0; change_mark=x; max_num=x; } void* Segtree :: operator new(size_t size) { C->change_mark=-1; return C++; } void Build_Tree(Segtree*&p,int x,int y) { int mid=x+y>>1; p=new Segtree; if(x==y) { p->max_num=posf[mid]; return ; } Build_Tree(p->ls,x,mid); Build_Tree(p->rs,mid+1,y); p->max_num=max(p->ls->max_num,p->rs->max_num); } void Change(Segtree*p,int x,int y,int z,int v) { int mid=x+y>>1; if(x==y) { p->max_num=v; return ; } if(~p->change_mark) { p->ls->Change(p->change_mark); p->rs->Change(p->change_mark); p->change_mark=-1; } if(p->add_mark) { p->ls->Add(p->add_mark); p->rs->Add(p->add_mark); p->add_mark=0; } if(z<=mid) Change(p->ls,x,mid,z,v); else Change(p->rs,mid+1,y,z,v); p->max_num=max(p->ls->max_num,p->rs->max_num); } void Change(Segtree*p,int x,int y,int l,int r,int v) { int mid=x+y>>1; if(x==l&&y==r) { p->Change(v); return ; } if(~p->change_mark) { p->ls->Change(p->change_mark); p->rs->Change(p->change_mark); p->change_mark=-1; } if(p->add_mark) { p->ls->Add(p->add_mark); p->rs->Add(p->add_mark); p->add_mark=0; } if(r<=mid) Change(p->ls,x,mid,l,r,v); else if(l>mid) Change(p->rs,mid+1,y,l,r,v); else Change(p->ls,x,mid,l,mid,v),Change(p->rs,mid+1,y,mid+1,r,v); p->max_num=max(p->ls->max_num,p->rs->max_num); } void Add(Segtree*p,int x,int y,int l,int r,int v) { int mid=x+y>>1; if(x==l&&y==r) { p->Add(v); return ; } if(~p->change_mark) { p->ls->Change(p->change_mark); p->rs->Change(p->change_mark); p->change_mark=-1; } if(p->add_mark) { p->ls->Add(p->add_mark); p->rs->Add(p->add_mark); p->add_mark=0; } if(r<=mid) Add(p->ls,x,mid,l,r,v); else if(l>mid) Add(p->rs,mid+1,y,l,r,v); else Add(p->ls,x,mid,l,mid,v),Add(p->rs,mid+1,y,mid+1,r,v); p->max_num=max(p->ls->max_num,p->rs->max_num); } int Get_Ans(Segtree*p,int x,int y,int l,int r) { int mid=x+y>>1; if(x==l&&y==r) return p->max_num; if(~p->change_mark) { p->ls->Change(p->change_mark); p->rs->Change(p->change_mark); p->change_mark=-1; } if(p->add_mark) { p->ls->Add(p->add_mark); p->rs->Add(p->add_mark); p->add_mark=0; } if(r<=mid) return Get_Ans(p->ls,x,mid,l,r); if(l>mid) return Get_Ans(p->rs,mid+1,y,l,r); return max( Get_Ans(p->ls,x,mid,l,mid) , Get_Ans(p->rs,mid+1,y,mid+1,r) ); } void Add(int x,int y,int z) { table[++tot].to=y; table[tot].f=z; table[tot].next=head[x]; head[x]=tot; } void DFS1(int x) { int i; dpt[x]=dpt[fa[x]]+1; size[x]=1; for(i=head[x];i;i=table[i].next) { if(table[i].to==fa[x]) continue; fa[table[i].to]=x; f[table[i].to]=table[i].f; DFS1(table[i].to); size[x]+=size[table[i].to]; if(size[table[i].to]>size[son[x]]) son[x]=table[i].to; } } void DFS2(int x) { int i; if(son[fa[x]]==x) top[x]=top[fa[x]]; else top[x]=x; posf[pos[x]=++cnt]=f[x]; if(son[x]) DFS2(son[x]); for(i=head[x];i;i=table[i].next) { if(table[i].to==fa[x]||table[i].to==son[x]) continue; DFS2(table[i].to); } } int Query(int x,int y) { int re=-2147483647,fx=top[x],fy=top[y]; while(fx!=fy) { if(dpt[fx]<dpt[fy]) swap(x,y),swap(fx,fy); re=max(re, Get_Ans(tree,1,n,pos[fx],pos[x]) ); fx=top[x=fa[fx]]; } if(x==y) return re; if(dpt[x]<dpt[y]) swap(x,y); re=max(re, Get_Ans(tree,1,n,pos[y]+1,pos[x]) ); return re; } void Change(int x,int y,int z) { int fx=top[x],fy=top[y]; while(fx!=fy) { if(dpt[fx]<dpt[fy]) swap(x,y),swap(fx,fy); Change(tree,1,n,pos[fx],pos[x],z); fx=top[x=fa[fx]]; } if(x==y) return ; if(dpt[x]<dpt[y]) swap(x,y); Change(tree,1,n,pos[y]+1,pos[x],z); } void _Add(int x,int y,int z) { int fx=top[x],fy=top[y]; while(fx!=fy) { if(dpt[fx]<dpt[fy]) swap(x,y),swap(fx,fy); Add(tree,1,n,pos[fx],pos[x],z); fx=top[x=fa[fx]]; } if(x==y) return ; if(dpt[x]<dpt[y]) swap(x,y); Add(tree,1,n,pos[y]+1,pos[x],z); } int main() { #ifdef PoPoQQQ freopen("1984.in","r",stdin); freopen("1984.out","w",stdout); #endif int i,x,y,z; char p[20]; cin>>n; for(i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&z); Add(x,y,z);Add(y,x,z); } DFS1(1); DFS2(1); Build_Tree(tree,1,n); while(1) { scanf("%s",p); switch(p[1]) { case 'a': scanf("%d%d",&x,&y); printf("%d\n", Query(x,y) ); break; case 'h': int temp; scanf("%d%d",&temp,&z); x=table[temp<<1].to; y=table[temp<<1|1].to; if(dpt[x]<dpt[y]) swap(x,y); Change(tree,1,n,pos[x],z); break; case 'o': scanf("%d%d%d",&x,&y,&z); Change(x,y,z); break; case 'd': scanf("%d%d%d",&x,&y,&z); _Add(x,y,z); break; case 't': return 0; } } }
BZOJ 1984 月下“毛景树” 树链剖分
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。