zoukankan      html  css  js  c++  java
  • 【线段树套平衡树】【pb_ds】bzoj3196 Tyvj 1730 二逼平衡树

    线段树套pb_ds里的平衡树,在洛谷OJ上测试,后三个测试点TLE

    #include<cstdio>
    #include<algorithm>
    #include<ext/pb_ds/assoc_container.hpp>
    #include<ext/pb_ds/tree_policy.hpp>
    #define N 50010
    #define INF 2147483647
    using namespace std;
    using namespace __gnu_pbds;
    typedef pair<int,int> Point;
    typedef tree<Point,null_type,less<Point>,rb_tree_tag,tree_order_statistics_node_update> rb_tree;
    typedef rb_tree::iterator ITER;
    rb_tree T[N<<2];
    int a[N],tags[N],tag,n,m;
    void buildtree(int rt,int l,int r)
    {
    	if(l==r)
    	  {
    	  	T[rt].insert(Point(a[l],l));
    	  	return;
    	  }
    	int m=(l+r>>1);
    	buildtree(rt<<1,l,m);
    	buildtree(rt<<1|1,m+1,r);
    	T[rt]=T[rt<<1];
    	for(ITER it=T[rt<<1|1].begin();it!=T[rt<<1|1].end();++it)
    	  T[rt].insert(*it);
    }
    int Rank(int v,int TAG,int ql,int qr,int rt,int l,int r)
    {
    	if(ql<=l&&r<=qr)
    	  return T[rt].order_of_key(Point(v,TAG));
    	int m=(l+r>>1),res=0;
    	if(ql<=m) res+=Rank(v,TAG,ql,qr,rt<<1,l,m);
    	if(m<qr) res+=Rank(v,TAG,ql,qr,rt<<1|1,m+1,r);
    	return res;
    }
    int Pre(int v,int ql,int qr,int rt,int l,int r)
    {
    	if(ql<=l&&r<=qr)
    	  {
    	  	ITER it=T[rt].lower_bound(Point(v,0));
    	  	if(it==T[rt].begin()) return -INF;
    		--it;
    	  	return (*it).first;
    	  }
    	int m=(l+r>>1),res=-INF;
    	if(ql<=m) res=max(res,Pre(v,ql,qr,rt<<1,l,m));
    	if(m<qr) res=max(res,Pre(v,ql,qr,rt<<1|1,m+1,r));
    	return res;
    }
    int Nex(int v,int ql,int qr,int rt,int l,int r)
    {
    	if(ql<=l&&r<=qr)
    	  {
    	  	ITER it=T[rt].upper_bound(Point(v,INF));
    	  	if(it==T[rt].end())
    		  return INF;
    	  	return (*it).first;
    	  }
    	int m=(l+r>>1),res=INF;
    	if(ql<=m) res=min(res,Nex(v,ql,qr,rt<<1,l,m));
    	if(m<qr) res=min(res,Nex(v,ql,qr,rt<<1|1,m+1,r));
    	return res;
    }
    void Update(int p,int v,int rt,int l,int r)
    {
    	T[rt].erase(Point(a[p],tags[p]));
    	T[rt].insert(Point(v,tag));
    	if(l==r) return;
    	int m=(l+r>>1);
    	if(p<=m) Update(p,v,rt<<1,l,m);
    	else Update(p,v,rt<<1|1,m+1,r);
    }
    int Kth(int K,int ql,int qr)
    {
    	int l=0,r=100000000;
    	while(l<r)
    	  {
    	  	int m=(l+r>>1);
    	  	if(Rank(m,INF,ql,qr,1,1,n)>=K)
    	  	  r=m;
    	  	else
    	  	  l=m+1;
    	  }
    	return l;
    }
    int main()
    {
    //	freopen("bzoj3196.in","r",stdin);
    	int op,x,y,z;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i)
    	  {
    	  	scanf("%d",&a[i]);
    	  	tags[i]=i;
    	  }
    	tag=n;
    	buildtree(1,1,n);
    //	for(int i=1;i<=n*4;++i)
    //	  printf("%d ",(*T[i].begin()).second);
    //	puts("");
    	for(;m;--m)
    	  {
    	  	scanf("%d%d%d",&op,&x,&y);
    	  	if(op==1)
    	  	  {
    	  	  	scanf("%d",&z);
    	  	  	printf("%d
    ",Rank(z,0,x,y,1,1,n)+1);
    	  	  }
    	  	else if(op==2)
    	  	  {
    	  	  	scanf("%d",&z);
    	  	  	printf("%d
    ",Kth(z,x,y));
    	  	  }
    	  	else if(op==3)
    	  	  {
    	  	  	++tag;
    	  	  	Update(x,y,1,1,n);
    	  	  	a[x]=y;
    	  	  	tags[x]=tag;
    	  	  }
    	  	else if(op==4)
    	  	  {
    	  	  	scanf("%d",&z);
    	  	  	printf("%d
    ",Pre(z,x,y,1,1,n));
    	  	  }
    	  	else
    	  	  {
    	  	  	scanf("%d",&z);
    	  	  	printf("%d
    ",Nex(z,x,y,1,1,n));
    	  	  }
    	  }
    	return 0;
    }
  • 相关阅读:
    玩转动态编译
    [源码]RandomId 生成随机字符串
    玩转动态编译:四、封装
    玩转动态编译:三、提高性能,抛弃反射
    玩转动态编译:一、初识
    封装和内置函数property classmethod staticmethod
    面向对象--命名空间和组合
    初始面向对象
    模块之序列化模块和包
    模块 time模块 sys模块 os模块
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/5934325.html
Copyright © 2011-2022 走看看