zoukankan      html  css  js  c++  java
  • BZOJ 3196 二逼平衡树 ——树套树

    【题目分析】

        全靠运气,卡空间。

        xjb试几次就过了。

    【代码】

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define maxn 200005
    #define mlog 16
    #define inf 0x3f3f3f3f
    #define maxm 4000005
    #define F(i,j,k) for (int i=j;i<=k;++i)
    
    int ch[maxm][2],fa[maxm],siz[maxm],v[maxm],num[maxm],n,m,rt[maxn*5],a[maxn];
    int L,R,X,C,tot,Pre,Nxt,opt,ans,k,aim;
    
    void update(int k)
    {siz[k]=siz[ch[k][0]]+siz[ch[k][1]]+num[k];}
    
    int ins(int &k,int fat)
    {
    	if (!k){k=++tot;num[k]=siz[k]=1;v[k]=C;fa[k]=fat;ch[k][0]=ch[k][1]=0;return k;}
    	siz[k]++; 
    	if (C==v[k]) {num[k]++;return k;}
    	else if (C<v[k]) return ins(ch[k][0],k);
    	else return ins(ch[k][1],k);
    }
    
    void rot(int x,int &k)
    {
    	int y=fa[x],z=fa[y],l=0,r;
    	if (ch[y][1]==x) l=1; r=l^1;
    	if (y==k) k=x;
    	else
    	{
    		if (ch[z][0]==y) ch[z][0]=x;
    		else ch[z][1]=x;
    	}
    	fa[x]=z; fa[y]=x; fa[ch[x][r]]=y;
    	ch[y][l]=ch[x][r]; ch[x][r]=y;
    	update(y); update(x);
    	
    }
    
    void splay(int x,int &k)
    {
    	while (x!=k)
    	{
    		int y=fa[x],z=fa[y];
    		if (y!=k)
    		{
    			if (ch[z][0]==y^ch[y][0]==x) rot(x,k);
    			rot(y,k);
    		}
    		rot(x,k);
    	}
    }
    
    void add(int o,int l,int r)
    {
    	int mid=l+r>>1;
    	splay(ins(rt[o],0),rt[o]);
    	if (l==r) return;
    	if (X<=mid) add(o<<1,l,mid);
    	else add(o<<1|1,mid+1,r);
    }
    
    void qrk(int k)
    {
    	if (!k) return;
    	if (v[k]<C) {ans+=siz[ch[k][0]]+num[k];return qrk(ch[k][1]);}
    	if (v[k]==C) {ans+=siz[ch[k][0]];return;}
    	return qrk(ch[k][0]);
    }
    
    void queryrk(int o,int l,int r)
    {
    	if (L<=l&&r<=R){qrk(rt[o]);return;}
    	int mid=l+r>>1;
    	if (L<=mid) queryrk(o<<1,l,mid);
    	if (R>mid) queryrk(o<<1|1,mid+1,r);
    }
    
    void qpr(int k)
    {
    	if (!k) return;
    	if (v[k]>=C) return qpr(ch[k][0]);
    	else{Pre=max(Pre,v[k]); return qpr(ch[k][1]);}
    }
    
    void querypr(int o,int l,int r)
    {
    	if (L<=l&&r<=R){qpr(rt[o]);return;}
    	int mid=l+r>>1;
    	if (L<=mid) querypr(o<<1,l,mid);
    	if (R>mid) querypr(o<<1|1,mid+1,r);
    }
    
    void qnt(int k)
    {
    	if (!k) return;
    	if (v[k]<=C) return qnt(ch[k][1]);
    	else{Nxt=min(Nxt,v[k]); return qnt(ch[k][0]);}
    }
    
    void querynt(int o,int l,int r)
    {
    	if (L<=l&&r<=R){qnt(rt[o]);return;}
    	int mid=l+r>>1;
    	if (L<=mid) querynt(o<<1,l,mid);
    	if (R>mid) querynt(o<<1|1,mid+1,r);
    }
    
    void del(int &k)
    {
    	if (v[k]==C)
    	{
    		if (num[k]>1)
    		{
    			num[k]--;
    			siz[k]--;
    			splay(k,rt[aim]);
    			return ;
    		}
    		else
    		{
    			if (ch[k][0]*ch[k][1]==0)
    			{
    				if ((!ch[k][0])&&(!ch[k][1])) {k=0;return;}
    				if (!ch[k][0]) fa[ch[k][1]]=fa[k];
    				else fa[ch[k][0]]=fa[k];
    				k=ch[k][0]+ch[k][1];
    				return ;
    			}
    			else
    			{
    				int tmp=rand()%2;
    				rot(ch[k][tmp],k);
    				del(k);
    				return ;
    			}
    		}
    	}
    	siz[k]--;
    	if (v[k]<C) del(ch[k][1]);
    	else del(ch[k][0]);
    }
    
    void dec(int o,int l,int r)
    {
    	int mid=(l+r)/2;aim=o;
    	del(rt[o]);
    	if (l==r) return ;
    	if (X<=mid) dec(o<<1,l,mid);
    	else dec(o<<1|1,mid+1,r);
    }
    
    int main()
    {
    	int l,r;
    //	freopen("in.txt","r",stdin);
    	scanf("%d%d",&n,&m);
    	F(i,1,n)
    	{
    		scanf("%d",&a[i]);
    		X=i; C=a[i];
    		add(1,1,n);
    	}
    	F(i,1,m)
    	{
    		scanf("%d",&opt);
    		switch(opt)
    		{
    			case 1:
    				ans=0;
    				scanf("%d%d%d",&L,&R,&C);
    				queryrk(1,1,n);
    				printf("%d
    ",ans+1);
    			break;
    			case 2:
    				scanf("%d%d%d",&L,&R,&k);
    				l=-inf; r=inf;
    				while (l<r)
    				{
    					int mid=(l+r)/2+1;
    					C=mid; ans=0;
    					queryrk(1,1,n);
    					if (ans<=k-1) l=mid;
    					else r=mid-1;
    				}
    				printf("%d
    ",r);
    			break;
    			case 3:
    				scanf("%d%d",&X,&k);
    				C=a[X];
    				dec(1,1,n);
    				a[X]=k; C=a[X];
    				add(1,1,n);
    			break;
    			case 4:
    				Pre=-inf;
    				scanf("%d%d%d",&L,&R,&C);
    				querypr(1,1,n);
    				printf("%d
    ",Pre);
    			break;
    			case 5:
    				Nxt=inf;
    				scanf("%d%d%d",&L,&R,&C);
    				querynt(1,1,n);
    				printf("%d
    ",Nxt);
    			break;
    		}
    	}
    }
    

      

  • 相关阅读:
    VS创建C工程
    信用卡诈骗分析
    R语言parse函数与eval函数的字符串转命令行及执行操作
    用R语言提取数据框中日期对应年份(列表转矩阵)
    R语言模型选择之精度准则与最大值法问题
    对数据集做标准化处理的几种方法——基于R语言
    可视化缺失值的办法——R语言
    模型验证方法——R语言
    R语言 绘图——条形图可以将堆积条形图与百分比堆积条形图配合使用
    R语言抽样的问题
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6399614.html
Copyright © 2011-2022 走看看