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("");
        }
    }
    
  • 相关阅读:
    long和Long的区别
    C语言的变量的内存分配
    Java蓝桥杯 算法提高 九宫格
    Java实现 蓝桥杯算法提高金明的预算方案
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
  • 原文地址:https://www.cnblogs.com/lcxer/p/10530411.html
Copyright © 2011-2022 走看看