zoukankan      html  css  js  c++  java
  • 平衡树入门

    BZOJ1588

    http://www.lydsy.com/JudgeOnline/problem.php?id=1588

    splay维护一下前驱后继

    #include<cstdio>
    #define FOR(i,s,t) for(register int i=s;i<=t;++i)
    inline int min(int a,int b){
    	return a<b?a:b;
    }
    const int N=100011,inf=(1<<30);
    int num1,num2;
    int n,x,ans;
    namespace Splay{
    	int sz,rt;
    	int to[N][2],fa[N],num[N];
    	inline void rotate(int x,int &k){
    		register int y=fa[x],z=fa[y],l,r;
    		l=(x==to[y][0]?0:1);r=l^1;
    		if(y==k)
    			k=x;
    		else 
    			to[z][0]==y?to[z][0]=x:to[z][1]=y;
    		fa[x]=z;fa[y]=x;fa[to[x][r]]=y;
    		to[y][l]=to[x][r];to[x][r]=y;
    	}
    	inline void modify(int x,int &k){
    		register int y,z;
    		while(x!=k){
    			y=fa[x];z=fa[y];
    			if(y!=k)((to[y][0]==x)^(to[z][0]==y))?rotate(x,k):rotate(y,k);
    			rotate(x,k);
    		}
    	}
    	inline void insert(int &k,int x,int father=0){
    		if(!k){
    			k=++sz;
    			fa[k]=father;
    			num[k]=x;
    			modify(k,rt);
    			return ;
    		}
    		x<num[k]?insert(to[k][0],x,k):insert(to[k][1],x,k);
    	}
    	inline void ask_before(int k,int x){
         	if(!k)return;
         	if(num[k]<=x){
    	 		num1=num[k];
    			ask_before(to[k][1],x);
    		}
        	else 
    			ask_before(to[k][0],x);
     	}
    	inline void ask_after(int k,int x){
       		if(!k)return;
       		if(num[k]>=x){
    		   	num2=num[k];
    			ask_after(to[k][0],x);
    		}
       		else 
    		   	ask_after(to[k][1],x);
    	}
    }
    using namespace Splay;
    int main(){
    	scanf("%d",&n);
    	FOR(i,1,n){
    		num1=-inf;num2=inf;
    		scanf("%d",&x);
    		ask_after(rt,x);
    		ask_before(rt,x);
    		ans+=(i!=1?min(num2-x,x-num1):x);
    		insert(rt,x);
    	}
    	printf("%d",ans);
    	return 0;
    }
    

      

    或者写棵值域线段树冷静一下

    #include<cstdio>
    #include<algorithm>
    #define FOR(i,s,t) for(register int i=s;i<=t;++i)
    #define ls k<<1,l,mid
    #define rs k<<1|1,mid+1,r
    #define gc getchar()
    using namespace std;
    const int N=400011,inf=1e9;
    int n,pos,ans;
    int a[N],b[N];
    inline int min(int a,int b){
    	return a<b?a:b;
    }
    namespace Segment_Tree{
    	int tr[N];
    	inline int query_rank(int x,int k=1,int l=1,int r=40000){
    		++tr[k];
    		if(l==r)return 1;
    		int mid=(l+r)>>1;
    		return x<=mid?query_rank(x,ls):(tr[k<<1]+query_rank(x,rs));
    	}
    	inline int query_num(int x,int k=1,int l=1,int r=40000){
    		if(l==r)return l;
    		int mid=(l+r)>>1;
    		return x<=tr[k<<1]?query_num(x,ls):query_num(x-tr[k<<1],rs);
    	}
    }
    using namespace Segment_Tree;
    inline void disc_init(){
    	sort(b+1,b+b[0]+1);
    	b[0]=unique(b+1,b+b[0]+1)-b-1;
    	FOR(i,1,n)
    		a[i]=lower_bound(b+1,b+b[0]+1,a[i])-b;
    }
    int main(){
    	scanf("%d",&n);
    	b[++b[0]]=-inf,b[++b[0]]=inf;
    	FOR(i,1,n)scanf("%d",a+i),b[++b[0]]=a[i];
    	disc_init();
    	query_rank(1),query_rank(b[0]);
    	FOR(i,1,n){
    		pos=query_rank(a[i]);
    		ans+=(i==1?b[a[i]]:min(b[a[i]]-b[query_num(pos-1)],b[query_num(pos+1)]-b[a[i]]));
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    用Java socket (TCP通信模型)实现一个简单的web 服务器
    java.net.BindException: 权限不够
    java 反射机制探究
    java程序执行顺序
    python 安装第三方库,超时报错--Read timed out.
    RTTI和反射
    Ubuntu 16.04
    20160515-hibernate--事务
    Ubuntu 16.04
    python--继承和多态
  • 原文地址:https://www.cnblogs.com/Stump/p/8120481.html
Copyright © 2011-2022 走看看