zoukankan      html  css  js  c++  java
  • P4115 Qtree4

    链接

    写一个 (LCT) 做法。

    对于一个以 (x) 为根的 (splay) ,设 (mx_x) 为以 (x) 为根的子树中的答案,显然可以与 (ls_x,rs_x) 与虚子树中的 (mx) 取最大值。

    显然只有经过 (x) 的链没有计算,我们考虑 (x) 本身,(ls_x,rs_x) 和虚子树中白点离 (x) 最远的距离,它们中任意两个相加都可以更新答案,以及虚子树中的最长链与次长链相加也可以更新答案。

    如何维护它们呢?设 (lx_x) 为以 (x) 为根的 (splay) 中白点离最左端的点的最长距离,(ls_x) 中白点离 (x) 最远的距离即可通过 (rx_{ls_x}) 得出,(rx_x) 同理。

    (lx_x) 可以由 (lx_{ls_x})(lx_{rs_x}) 与虚子树最长链加上左部分的边的总权值得到,(rx_x) 同理。

    边权可以拆边或直接赋到点上维护,这里用第二种方法,常数小,但边权处理稍显复杂。

    (frak{code})

    #include<bits/stdc++.h>
    #define IL inline
    #define LL long long
    #define ls(x) ch[x][0]
    #define rs(x) ch[x][1]
    using namespace std;
    const int N=1e5+3,inf=1e9;
    struct hh{
    	int to,nxt,w;
    }e[N<<1];
    int n,m,num,siz,ans,val[N],col[N],fir[N];
    int fa[N],ch[N][2],vsum[N],lx[N],rx[N],mx[N],lv[N];
    IL int in(){
    	char c;int f=1;
    	while((c=getchar())<'0'||c>'9')
    	  if(c=='-') f=-1;
    	int x=c-'0';
    	while((c=getchar())>='0'&&c<='9')
    	  x=x*10+c-'0';
    	return x*f;
    }
    struct heap{
    	priority_queue<int>q1,q2;int siz;
    	IL void pre(){while(q2.size()&&q1.top()==q2.top()) q1.pop(),q2.pop();}
    	IL void push(int x){q1.push(x),++siz;}
    	IL void pop(int x){q2.push(x),--siz;}
    	IL int top(){pre();return siz?q1.top():-inf;}
    	IL int ask(){
    		if(siz<2) return -inf;
    		int x=top();pop(x);
    		int y=top();push(x);
    		return x+y;
    	}
    }q1[N],q2[N];
    IL int max(int x,int y){return x>y?x:y;}
    IL int min(int x,int y){return x<y?x:y;}
    IL int chk(int x){return rs(fa[x])==x;}
    IL int noroot(int x){return ls(fa[x])==x||rs(fa[x])==x;}
    IL void pushup(int x){
    	vsum[x]=vsum[ls(x)]+vsum[rs(x)]+val[x],
    	mx[x]=max(mx[ls(x)],mx[rs(x)]),
    	lv[x]=ls(x)?lv[ls(x)]:val[x];
    	int Max=max(q1[x].top(),col[x]);
    	lx[x]=max(lx[ls(x)],max(lx[rs(x)]+lv[rs(x)],Max)+val[x]+vsum[ls(x)]-lv[x]),
    	rx[x]=max(rx[rs(x)],max(rx[ls(x)]+val[x],Max)+vsum[rs(x)]),
    	mx[x]=max(mx[x],max(q1[x].ask(),q2[x].top())),
    	mx[x]=max(mx[x],lx[rs(x)]+lv[rs(x)]+rx[ls(x)]+val[x]),
    	mx[x]=max(mx[x],max(Max+rx[ls(x)]+val[x],Max+lx[rs(x)]+lv[rs(x)]));
    	if(!col[x]) mx[x]=max(mx[x],q1[x].top());
    }
    IL void rotate(int x){
    	int y=fa[x],z=fa[y],k=chk(x),w=ch[x][k^1];
    	if(noroot(y)) ch[z][chk(y)]=x;
    	if(w) fa[w]=y;
    	fa[y]=x,fa[x]=z,ch[x][k^1]=y,ch[y][k]=w;
    	pushup(y);
    }
    IL void splay(int x){
    	while(noroot(x)){
    		int y=fa[x];
    		if(noroot(y))
    		  rotate(chk(x)^chk(y)?x:y);
    		rotate(x);
    	}
    	pushup(x);
    }
    IL void access(int x){
    	for(int y=0;x;x=fa[y=x]){
    		splay(x);
    		if(rs(x)) q1[x].push(lx[rs(x)]+lv[rs(x)]),q2[x].push(mx[rs(x)]);
    		if(rs(x)=y) q1[x].pop(lx[rs(x)]+lv[rs(x)]),q2[x].pop(mx[rs(x)]);
    		pushup(x);
    	}
    }
    IL void add(int x,int y,int z){e[++num]=(hh){y,fir[x],z},fir[x]=num;}
    void dfs(int u,int f){
    	for(int i=fir[u],v;v=e[i].to;i=e[i].nxt)
    	  if(v^f){
    	  	fa[v]=u,val[v]=e[i].w,dfs(v,u),
    			q1[u].push(lx[v]+lv[v]),q2[u].push(mx[v]);
    		}
    	pushup(u);
    }
    int main()
    {
    	char op[10];int x,y,z;
    	siz=n=in(),lx[0]=rx[0]=mx[0]=-inf;
    	for(int i=1;i<n;++i)
    	  x=in(),y=in(),z=in(),
    	  add(x,y,z),add(y,x,z);
    	dfs(1,0),ans=mx[1],m=in();
    	while(m--){
    		scanf("%s",op+1);
    		if(op[1]=='C'){
    			x=in(),access(x),splay(x);
    			if(col[x]) col[x]=0,++siz;
    			else col[x]=-inf,--siz;
    			pushup(x),ans=mx[x];
    		}
    		else{
    			if(siz==1) printf("0
    ");
    			else if(!siz) printf("They have disappeared.
    ");
    			else printf("%d
    ",max(0,ans));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Oracle ORA07445 [evaopn3()+384] 错误 分析
    Openfiler iscsiadm: No portals found 解决方法
    Openfiler iscsiadm: No portals found 解决方法
    ORA00600 [kmgs_parameter_update_timeout_1], [27072] ORA27072 解决方法
    Oracle 安装 Error in writing to directory /tmp/OraInstall 错误 说明
    Oracle alert log ALTER SYSTEM SET service_names='','SYS$SYS.KUPC$C_...' SCOPE=MEMORY SID='' 说明
    Oracle latch:library cache 导致 数据库挂起 故障
    ORA600 [4194] 说明
    ORA00600:[32695], [hash aggregation can't be done] 解决方法
    Oracle 10g Rac root.sh Failure at final check of Oracle CRS stack 10 解决方法
  • 原文地址:https://www.cnblogs.com/yiqiAtiya/p/14292291.html
Copyright © 2011-2022 走看看