zoukankan      html  css  js  c++  java
  • BZOJ 4855 [Jsoi2016]轻重路径

    题解:用树链剖分来维护树链剖分

    令d[x]=size[heavyson[x]]-size[lightson[x]]

    当d[x]<0时轻重儿子关系改变

    用数据结构维护d[x]并找到这些位置改变即可

    时间复杂度O(不会分析)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define lo now<<1
    #define ro now<<1|1
    using namespace std;
    const int maxn=200009;
    
    int n,m;
    
    long long nowans=0;
    int havein[maxn],root=0;
    int del[maxn];
    
    int ls[maxn],rs[maxn];
    int father[maxn],siz[maxn],dep[maxn];
    int idp[maxn],top[maxn],ref[maxn],hson[maxn];
    void Dfs1(int now,int fa){
    	father[now]=fa;
    	dep[now]=dep[fa]+1;
    	siz[now]=1;
    	if(ls[now]){
    		Dfs1(ls[now],now);
    		siz[now]+=siz[ls[now]];
    		if(siz[ls[now]]>siz[hson[now]])hson[now]=ls[now];
    	}
    	if(rs[now]){
    		Dfs1(rs[now],now);
    		siz[now]+=siz[rs[now]];
    		if(siz[rs[now]]>siz[hson[now]])hson[now]=rs[now];
    	}
    }
    
    
    int dfsclock=0;
    void Dfs2(int now,int toppoint){
    	if(now==toppoint)nowans-=now;
    	
    	idp[now]=++dfsclock;
    	ref[dfsclock]=now;
    	top[now]=toppoint;
    	if(!hson[now])return;
    	Dfs2(hson[now],toppoint);
    	if((ls[now])&&(ls[now]!=hson[now]))Dfs2(ls[now],ls[now]);
    	if((rs[now])&&(rs[now]!=hson[now]))Dfs2(rs[now],rs[now]);
    }
    
    struct SegmentTree{
    	int l,r;
    	int tag,mn;//siz[heavy[now]]-siz[light[son]]
    	int havetop;//father[top[now]]
    }tree[maxn<<2];
    inline void pushup(int now){
    	tree[now].mn=min(tree[lo].mn,tree[ro].mn);
    	tree[now].havetop=(tree[lo].havetop|tree[ro].havetop);
    }
    inline void pushdown(int now){
    	if(tree[now].tag){
    		tree[lo].tag+=tree[now].tag;
    		tree[ro].tag+=tree[now].tag;
    		tree[lo].mn+=tree[now].tag;
    		tree[ro].mn+=tree[now].tag;
    		tree[now].tag=0;
    	}
    }
    
    void BuildTree(int now,int l,int r){
    	tree[now].l=l;tree[now].r=r;
    	tree[now].tag=0;
    	if(l==r){
    		int x=ref[l];
    		tree[now].mn=siz[hson[x]]-min(siz[ls[x]],siz[rs[x]]);
    		tree[now].havetop=0;
    		return;
    	}
    	int mid=(l+r)>>1;
    	BuildTree(lo,l,mid);
    	BuildTree(ro,mid+1,r);
    	pushup(now);
    }
    
    void Updatasec(int now,int ll,int rr,int x){
    	if(tree[now].l>=ll&&tree[now].r<=rr){
    		tree[now].tag+=x;
    		tree[now].mn+=x;
    		return;
    	}
    	int mid=(tree[now].l+tree[now].r)>>1;
    	pushdown(now);
    	if(ll<=mid)Updatasec(lo,ll,rr,x);
    	if(rr>mid)Updatasec(ro,ll,rr,x);
    	pushup(now);
    }
    
    void Updatatop(int now,int ll,int rr,int x){
    	if(ll>rr)return;
    	if(tree[now].r<ll)return;
    	if(tree[now].l>rr)return;
    	if(tree[now].l==tree[now].r){
    		tree[now].mn+=x;
    		return;
    	}
    	pushdown(now);
    	if(tree[lo].havetop)Updatatop(lo,ll,rr,x);
    	if(tree[ro].havetop)Updatatop(ro,ll,rr,x);
    	pushup(now);
    }
    
    void Changetop(int now,int ll,int rr){
    	if(ll>rr)return;
    	if(tree[now].r<ll)return;
    	if(tree[now].l>rr)return;
    	if(tree[now].l==tree[now].r){
    		tree[now].mn=-tree[now].mn;
    		tree[now].havetop=1;
    		int x=ref[tree[now].l];
    		if(ls[x]==hson[x]){
    			nowans=nowans-ls[x]+rs[x];
    			hson[x]=rs[x];
    		}else{
    			nowans=nowans-rs[x]+ls[x];
    			hson[x]=ls[x];
    		}
    		return;
    	}
    	pushdown(now);
    	if(tree[lo].mn<0)Changetop(lo,ll,rr);
    	if(tree[ro].mn<0)Changetop(ro,ll,rr);
    	pushup(now);
    }
    
    void Updatapoint(int now,int p,int x){
    	if(tree[now].l==tree[now].r){
    		tree[now].mn+=x;
    		if(tree[now].mn<0){
    			tree[now].mn=-tree[now].mn;
    			tree[now].havetop=0;
    			int o=ref[p];
    			if(ls[o]==hson[o]){
    				nowans=nowans-ls[o]+rs[o];
    				hson[o]=rs[o];
    			}else{
    				nowans=nowans-rs[o]+ls[o];
    				hson[o]=ls[o];
    			}
    		}
    		return;
    	}
    	int mid=(tree[now].l+tree[now].r)>>1;
    	pushdown(now);
    	if(p<=mid)Updatapoint(lo,p,x);
    	else Updatapoint(ro,p,x);
    	pushup(now);
    }
    
    void ChangePath(int u){
    	int x=u;
    	while(x){
    		int tx=top[x];
    		Updatasec(1,idp[tx],idp[x],-1);
    		
    		Updatatop(1,idp[tx],idp[x]-1,2);
    		Changetop(1,idp[tx],idp[x]-1);
    //		x=tx;int fa=father[x];
    //		if(!fa)break;
    //		if(hson[fa]!=x){ 
    //			Updatapoint(1,idp[fa],2);
    //		}else{
    //			Updatapoint(1,idp[fa],0);
    //		}
    		x=father[tx];tx=top[x];
    	}
    	x=u;
    	while(x){
    		x=top[x];
    		int fa=father[x];
    		if(!fa)break;
    			if(hson[fa]!=x){ 
    			Updatapoint(1,idp[fa],2);
    		}else{
    			Updatapoint(1,idp[fa],0);
    		}
    		x=fa;
    	}
    }
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i){
    		scanf("%d%d",&ls[i],&rs[i]);
    		havein[ls[i]]++;
    		havein[rs[i]]++;
    	}
    	for(int i=1;i<=n;++i)nowans+=i;
    	for(int i=1;i<=n;++i)if(!havein[i])root=i;
    	
    	Dfs1(root,0);
    	Dfs2(root,root);
    	BuildTree(1,1,n);
    	
    	scanf("%d",&m);
    	printf("%lld
    ",nowans);
    	del[0]=1;
    	while(m--){
    		int x;scanf("%d",&x);
    		
    		del[x]=1;
    		ChangePath(x);
    		if(ls[father[x]]==x){
    			if(del[rs[father[x]]])nowans-=x;
    		}else{
    			if(del[ls[father[x]]])nowans-=x;
    		}
    		printf("%lld
    ",nowans);
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    js控制两个日期相减
    下拉框只显示最初下拉框中的值和json返回array的交集
    js来进行字符串的转化和小数点后的截取
    js来实现popup的生成,带钟罩,可移动popup,点击body可自动消失
    css块居中
    響應式設計佈局
    pc端手機端自適應佈局方案
    pc端常規頁面實現
    pc端前端和手機端區別
    js字符串轉數組,數組轉字符串
  • 原文地址:https://www.cnblogs.com/zzyer/p/8546331.html
Copyright © 2011-2022 走看看