• BZOJ 3196 二逼平衡树


    为什么这么慢呢。。。。都是线段树套splay为什么就只能卡过去呢。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 50050
    #define maxm 4000050 
    #define inf 100000001
    using namespace std;
    int n,m,tot1=0,tot2=0,tr_root,root[maxn<<2],ls[maxn<<2],rs[maxn<<2],tmp=0,x[maxn],mn[maxn<<2];
    int tree[maxm][3],fath[maxm],size[maxm],cnt[maxm],val[maxm];
    int type,l,r,pos,k;
    int pre,sub,tmp1,tmp2;
    void reset(int x)
    {
        root[x]=++tot2;tree[root[x]][2]=++tot2;fath[tot2]=root[x];
        size[root[x]]=2;size[tot2]=1;
        val[root[x]]=-1;val[tot2]=inf;cnt[root[x]]=cnt[tot2]=1;
    }
    void pushup(int now) {size[now]=size[tree[now][1]]+size[tree[now][2]]+cnt[now];}
    void sg_build(int &now,int left,int right)
    {
        now=++tot1;reset(now);mn[now]=inf;
        if (left==right) return;
        int mid=left+right>>1;
        sg_build(ls[now],left,mid);
        sg_build(rs[now],mid+1,right);
    }
    void insert(int &now,int father,int k)
    {
        if (!now)
        {
            now=++tot2;fath[now]=father;size[now]=cnt[now]=1;val[now]=k;
            return;
        }
        if (val[now]==k)
        {
            cnt[now]++;size[now]++;
            return;
        }
        if (k<val[now]) insert(tree[now][1],now,k);
        else insert(tree[now][2],now,k);
        pushup(now);
    }
    void rotate(int x,int &k)
    {
        int y=fath[x],z=fath[y],l,r;
        if (tree[y][1]==x) l=1;else l=2;r=3-l;
        if (y==k) k=x;
        else
        {
            if (tree[z][1]==y) tree[z][1]=x;
            else tree[z][2]=x;
        }
        fath[x]=z;fath[y]=x;fath[tree[x][r]]=y;
        tree[y][l]=tree[x][r];tree[x][r]=y;
        pushup(y);pushup(x);
    }
    void splay(int x,int &k)
    {
        while (x!=k)
        {
            int y=fath[x],z=fath[y];
            if (y!=k)
            {
                if ((tree[y][1]==x)^(tree[z][1]==y)) rotate(x,k);
                else rotate(y,k);
            }
            rotate(x,k);
        }
    }
    void sg_insert(int now,int left,int right,int pos,int k)
    {
        int ret=tot2;
        insert(root[now],0,k);
        if (ret!=tot2) splay(tot2,root[now]);
        if (left==right) return;
        int mid=left+right>>1;
        if (pos<=mid) sg_insert(ls[now],left,mid,pos,k);
        else sg_insert(rs[now],mid+1,right,pos,k);
    }
    void get_rank(int now,int k)
    {
        if (!now) return;
        if (val[now]<k) {tmp+=size[tree[now][1]]+cnt[now];get_rank(tree[now][2],k);}
        else if (val[now]==k) {tmp+=size[tree[now][1]];return;}
        else get_rank(tree[now][1],k);
    }
    void sg_get_rank(int now,int left,int right,int l,int r,int x)
    {
        if (left==l && right==r) {get_rank(root[now],x);tmp--;return;}
        int mid=left+right>>1;
        if (r<=mid) sg_get_rank(ls[now],left,mid,l,r,x);
        else if (l>=mid+1) sg_get_rank(rs[now],mid+1,right,l,r,x);
        else {sg_get_rank(ls[now],left,mid,l,mid,x);sg_get_rank(rs[now],mid+1,right,mid+1,r,x);}
    }
    int binary_search()
    {
        int left=0,right=inf-1,ans,mid;
        while (left<=right)
        {
            mid=left+right>>1;tmp=0;
            sg_get_rank(tr_root,1,n,l,r,mid);
            if (tmp+1<=k) {ans=mid;left=mid+1;}
            else right=mid-1;
        }
        return ans;
    }
    void find_pre(int now,int k)
    {
        if (!now) return;
        if (val[now]<k) {pre=now;find_pre(tree[now][2],k);}
        else find_pre(tree[now][1],k);
    }
    void find_sub(int now,int k)
    {
        if (!now) return;
        if (val[now]>k) {sub=now;find_sub(tree[now][1],k);}
        else find_sub(tree[now][2],k);
    }
    void delete_(int now,int k)
    {
        find_pre(root[now],k);find_sub(root[now],k);
        splay(pre,root[now]);
        splay(sub,tree[root[now]][2]);
        int x=root[now],y=tree[root[now]][2],z=tree[y][1];
        if (cnt[z]>1) {cnt[z]--;size[z]--;}
        else fath[z]=tree[y][1]=0;
        pushup(y);pushup(x);
    }
    void sg_delete(int now,int left,int right,int pos,int k)
    {
        delete_(now,k);
        if (left==right) return;
        int mid=left+right>>1;
        if (pos<=mid) sg_delete(ls[now],left,mid,pos,k);
        else sg_delete(rs[now],mid+1,right,pos,k);
    }
    void sg_find_ps(int now,int left,int right,int l,int r,int k,int type)
    {
        if (left==l && right==r)
        {
            if (type==1) {find_pre(root[now],k);tmp1=max(tmp1,val[pre]);}
            else {find_sub(root[now],k);tmp2=min(tmp2,val[sub]);}
            return;
        }
        int mid=left+right>>1;
        if (r<=mid) sg_find_ps(ls[now],left,mid,l,r,k,type);
        else if (l>=mid+1) sg_find_ps(rs[now],mid+1,right,l,r,k,type);
        else {sg_find_ps(ls[now],left,mid,l,mid,k,type);sg_find_ps(rs[now],mid+1,right,mid+1,r,k,type);}
    }
    void sg_mn_modify(int now,int left,int right,int pos,int k)
    {
        if (left==right) {mn[now]=k;return;}
        int mid=(left+right)>>1;
        if (pos<=mid) sg_mn_modify(ls[now],left,mid,pos,k);
        else sg_mn_modify(rs[now],mid+1,right,pos,k);
        mn[now]=min(mn[ls[now]],mn[rs[now]]);
    }
    int sg_mn_ask(int now,int left,int right,int l,int r)
    {
        if (left==l && right==r) return mn[now];
        int mid=(left+right)>>1;
        if (r<=mid) return sg_mn_ask(ls[now],left,mid,l,r);
        else if (l>=mid+1) return sg_mn_ask(rs[now],mid+1,right,l,r);
        else return min(sg_mn_ask(ls[now],left,mid,l,mid),sg_mn_ask(rs[now],mid+1,right,mid+1,r));
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        sg_build(tr_root,1,n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&x[i]);k=x[i];
            sg_insert(tr_root,1,n,i,k);
            sg_mn_modify(tr_root,1,n,i,k);
        }
        for (int i=1;i<=m;i++)
        {
            scanf("%d",&type);
            if (type==1) {scanf("%d%d%d",&l,&r,&k);tmp=0;sg_get_rank(tr_root,1,n,l,r,k);printf("%d
    ",tmp+1);}
            else if (type==2) {scanf("%d%d%d",&l,&r,&k);printf("%d
    ",binary_search());}
            else if (type==3) {scanf("%d%d",&pos,&k);sg_delete(tr_root,1,n,pos,x[pos]);x[pos]=k;sg_insert(tr_root,1,n,pos,k);sg_mn_modify(tr_root,1,n,pos,k);}
            else if (type==4) {scanf("%d%d%d",&l,&r,&k);tmp1=0;sg_find_ps(tr_root,1,n,l,r,k,1);printf("%d
    ",tmp1);}
            else 
            {
                scanf("%d%d%d",&l,&r,&k);
                if (k<0) printf("%d
    ",sg_mn_ask(tr_root,1,n,l,r));
                else
                {
                    tmp2=inf;
                    sg_find_ps(tr_root,1,n,l,r,k,2);
                    printf("%d
    ",tmp2);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    ORACLE备份脚本(4-RMAN1级增量备份)
    ORACLE备份脚本(3-RMAN0级全备)
    解决oracle数据库最大数据文件数超了
    ORACLE 数据库备份脚本(数据泵2-指定用户)
    oracle 数据库备份脚本(数据泵1-全库)
    Python操作hdfs
    ant实例
    Java网络编程客户端和服务器通信
    WordCount程序
    Python脚本开发练习
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6518449.html
Copyright © 2020-2023  润新知