zoukankan      html  css  js  c++  java
  • bzoj3196:Tyvj1730二逼平衡树

    传送门

    暴力啊,直接树套树上啊
    线段树套splay,卡卡常就直接A了
    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    void read(int &x) {
        char ch; bool ok;
        for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
        for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    void print(int x){
        if(x<0)putchar('-'),x=-x;
        if(x>9)print(x/10);
        putchar(x%10+'0');
    }
    #define rg register
    const int maxn=5e4+10;
    int n,m,a[maxn],cnt[maxn*30],size[maxn*30],ch[maxn*30][2],rt[maxn*4],f[maxn*30],id,v[maxn*30],tot;
    struct splay_tree
    {
        void update(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+cnt[x];}
        void move(int &k,int x)
        {
            int tmp=ch[f[x]][1]==x,fa=f[x],faa=f[fa];
            if(k==fa)k=x;
            else ch[faa][ch[faa][1]==fa]=x;
            ch[fa][tmp]=ch[x][tmp^1];f[ch[x][tmp^1]]=fa;
            ch[x][tmp^1]=fa,f[x]=faa,f[fa]=x;
            update(fa),update(x);
        }
        void splay(int &k,int x)
        {
            while(k!=x)
            {
                int y=f[x],z=f[y];
                if(y!=k)
                {
                    if((ch[y][0]==x)^(ch[z][0]==y))move(k,y);
                    else move(k,x);
                }
                move(k,x);
            }
        }
        int get_pre(int k)
        {
        	int now=ch[rt[k]][0];
        	while(ch[now][1])now=ch[now][1];
        	return now;
        }
        void del(int k,int x)
        {
        	splay(rt[k],x);
        	if(!ch[x][0]&&!ch[x][1]){rt[k]=0;return ;}
        	else if(!ch[x][0]&&ch[x][1]){rt[k]=ch[x][1],f[rt[k]]=0;return ;}
        	else if(ch[x][0]&&!ch[x][1]){rt[k]=ch[x][0],f[rt[k]]=0;return ;}
    		int g=get_pre(k);splay(rt[k],g);
    		ch[g][1]=ch[x][1],f[ch[x][1]]=g;update(g);
    	}
        void insert(int z,int x,int y)
        {
            if(!rt[z]){rt[z]=++id,v[rt[z]]=x,size[rt[z]]=cnt[rt[z]]=1;return ;}
            int now=rt[z];
            while(1)
            {
                if(x==v[now]){cnt[now]+=y,update(now);if(!cnt[now])del(z,now);else splay(rt[z],now);return ;}
                else if(x<v[now])
                {
                    if(!ch[now][0])
                    {
                        ch[now][0]=++id,size[id]=cnt[id]=1;
                        v[id]=x,f[id]=now;
                        update(now);break;
                    }
                    else now=ch[now][0];
                }
                else 
                {
                    if(!ch[now][1])
                    {
                        ch[now][1]=++id,size[id]=cnt[id]=1;
                        v[id]=x,f[id]=now;
                        update(now);break;
                    }
                    else now=ch[now][1];
                }
            }
            splay(rt[z],id);
        }
        int findmn(int k,int x)
        {
            if(!k||!x)return 0;
            if(v[k]==x)return size[ch[k][0]];
            if(v[k]>x)return findmn(ch[k][0],x);
            return size[ch[k][0]]+cnt[k]+findmn(ch[k][1],x);
        }
        int findmx(int k,int x)
        {
            if(!k||!x)return 0;
            if(v[k]==x)return size[ch[k][0]]+cnt[k];
            if(v[k]>x)return findmx(ch[k][0],x);
            return size[ch[k][0]]+cnt[k]+findmx(ch[k][1],x);
        }
        int find(int k,int x)
        {
        	if(!k)return 0;
        	if(x<=size[ch[k][0]])return find(ch[k][0],x);
        	if(x>size[ch[k][0]]&&x<=size[ch[k][0]]+cnt[k])return v[k];
        	return find(ch[k][1],x-size[ch[k][0]]-cnt[k]);
        }
        int pre(int k,int x)
        {
        	int tmp=find(rt[k],findmn(rt[k],x));
            return tmp?tmp:-2147483647;
        }
        int nxt(int k,int x)
        {
        	int tmp=find(rt[k],findmx(rt[k],x)+1);
            return tmp?tmp:2147483647;
        }
    }s[maxn*4];
    void change(int x,int l,int r,int a,int b,int c)
    {
        s[x].insert(x,b,c);
        if(l==r)return ;int mid=(l+r)>>1;
        if(a<=mid)change(x<<1,l,mid,a,b,c);
        else change(x<<1|1,mid+1,r,a,b,c);
    }
    int query(int x,int l,int r,int a,int b,int c)
    {
        if(a<=l&&b>=r)return s[x].findmn(rt[x],c);
        int mid=(l+r)>>1,ans=0;
        if(a<=mid)ans+=query(x<<1,l,mid,a,b,c);
        if(b>mid)ans+=query(x<<1|1,mid+1,r,a,b,c);
        return ans;
    }
    int find_pre(int x,int l,int r,int a,int b,int c)
    {
        if(a<=l&&b>=r){return s[x].pre(x,c);}
        int mid=(l+r)>>1,ans=-2147483647;
        if(a<=mid)ans=max(ans,find_pre(x<<1,l,mid,a,b,c));
        if(b>mid)ans=max(ans,find_pre(x<<1|1,mid+1,r,a,b,c));
        return ans;
    }
    int find_nxt(int x,int l,int r,int a,int b,int c)
    {
        if(a<=l&&b>=r){return s[x].nxt(x,c);}
        int mid=(l+r)>>1,ans=2147483647;
        if(a<=mid)ans=min(ans,find_nxt(x<<1,l,mid,a,b,c));
        if(b>mid)ans=min(ans,find_nxt(x<<1|1,mid+1,r,a,b,c));
        return ans;
    }
    bool check(int x,int y,int z,int k){return query(1,1,n,y,z,x)+1<=k;}
    int main()
    {
        read(n),read(m);
        for(rg int i=1;i<=n;i++)read(a[i]),change(1,1,n,i,a[i],1);
        for(rg int i=1,opt,x,y,z;i<=m;i++)
        {
            read(opt),read(x),read(y);
            if(opt==1)read(z),print(query(1,1,n,x,y,z)+1),puts("");
            if(opt==2)
            {
                read(z);int l=0,r=1e8;
                while(l<=r)
                {
                    int mid=(l+r)>>1;
                    if(check(mid,x,y,z))l=mid+1;
                    else r=mid-1;
                }
                print(r);puts("");
            }
            if(opt==3)change(1,1,n,x,a[x],-1),a[x]=y,change(1,1,n,x,a[x],1);
            if(opt==4)read(z),print(find_pre(1,1,n,x,y,z)),puts("");
            if(opt==5)read(z),print(find_nxt(1,1,n,x,y,z)),puts("");
        }
    }
    
  • 相关阅读:
    技术为辅,思维主导
    阶段性目标的设置
    非计算机专业测试之路
    第四章 Appium真机运行测试用例讲解
    第三章 Appium API介绍
    第二章 测试环境搭建(下)
    第二章 测试环境搭建(上)
    第一章 Appium简介
    测试人员的工作经验值钱吗
    2017 年该学习的编程语言、框架和工具
  • 原文地址:https://www.cnblogs.com/lcxer/p/10530411.html
Copyright © 2011-2022 走看看