• BZOJ1552: [Cerc2007]robotic sort & BZOJ3506: [Cqoi2014]排序机械臂


    【传送门:BZOJ1552&BZOJ3506


    简要题意:

      给出一个长度为n的序列,现在要将它们进行排序,排序的操作为:

      如果当前是第i次排序,则先找到当前序列中的最i小值所在位置x(如果有多个,则找到一开始给出序列顺序中排在最前面的数),然后将第i到第x的位置上的数都翻转

      求出每次操作中x的值


    题解:

      splay裸题,树上记录最小值以及如果有多个最小值时初始位置最小的数在树上的位置,以及翻转标记

      然后每做完一次操作,就要把x从树中删掉就行了


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #define Maxn 110000
    #define INF 1<<30
    using namespace std;
    struct T{int f,son[2],c,d,p,mp,mn;bool fz;T(){mn=INF;fz=false;}}tr[Maxn];int len;
    int rt,a[Maxn];
    void update(int x)
    {
        int lc=tr[x].son[0],rc=tr[x].son[1];
        int mmin=min(tr[x].d,min(tr[lc].mn,tr[rc].mn)),t=INF;
        if(tr[x].d==mmin) if(t>tr[x].p) t=tr[x].p;
        if(tr[lc].mn==mmin) if(t>tr[lc].mp) t=tr[lc].mp;
        if(tr[rc].mn==mmin) if(t>tr[rc].mp) t=tr[rc].mp;
        tr[x].mn=mmin;tr[x].mp=t;
        tr[x].c=tr[lc].c+tr[rc].c+(tr[x].d!=INF);
    }
    int ins(int l,int r)
    {
        int mid=(l+r)/2;
        int now=++len;
        tr[now].d=a[mid];tr[now].p=mid;
        if(l<mid) tr[now].son[0]=ins(l,mid-1),tr[tr[now].son[0]].f=now;
        if(mid<r) tr[now].son[1]=ins(mid+1,r),tr[tr[now].son[1]].f=now;
        update(now);
        return now;
    }
    void reverse(int x)
    {
        int lc=tr[x].son[0],rc=tr[x].son[1];
        if(lc!=0) tr[lc].fz^=1;
        if(rc!=0) tr[rc].fz^=1;
        swap(tr[x].son[0],tr[x].son[1]);
        tr[x].fz^=1;
    }
    void rotate(int x,int w)
    {
        int f=tr[x].f,ff=tr[f].f;
        int r,R;
        r=tr[x].son[w];R=f;
        tr[R].son[1-w]=r;
        if(r!=0) tr[r].f=R;
        r=x;R=ff;
        if(tr[R].son[0]==f) tr[R].son[0]=r;
        else tr[R].son[1]=r;
        tr[r].f=R;
        r=f;R=x;
        tr[R].son[w]=r;
        tr[r].f=R;
        update(f);
        update(x);
    }
    int s[Maxn],tot;
    void splay(int x,int tp)
    {
        int i=x,tot=0;
        while(tr[i].f!=tp)
        {
            s[++tot]=i;
            i=tr[i].f;
        }
        s[++tot]=i;
        while(tot!=0)
        {
            i=s[tot--];
            if(tr[i].fz==true) reverse(i);
        }
        while(tr[x].f!=tp)
        {
            int f=tr[x].f,ff=tr[f].f;
            if(ff==tp)
            {
                if(tr[f].son[0]==x) rotate(x,1);
                else rotate(x,0);
            }
            else
            {
                if(tr[f].son[0]==x&&tr[ff].son[0]==f){rotate(f,1);rotate(x,1);continue;}
                if(tr[f].son[0]==x&&tr[ff].son[1]==f){rotate(x,1);rotate(x,0);continue;}
                if(tr[f].son[1]==x&&tr[ff].son[0]==f){rotate(x,0);rotate(x,1);continue;}
                if(tr[f].son[1]==x&&tr[ff].son[1]==f){rotate(f,0);rotate(x,0);continue;}
            }
        }
        if(tp==0) rt=x;
    }
    void del(int x)
    {
        splay(x,0);
        if(tr[x].son[0]==0&&tr[x].son[1]==0) rt=0;
        else if(tr[x].son[0]==0&&tr[x].son[1]!=0) rt=tr[x].son[1],tr[rt].f=0;
        else if(tr[x].son[0]!=0&&tr[x].son[1]==0) rt=tr[x].son[0],tr[rt].fz^=1,tr[rt].f=0;
        else
        {
            if(tr[x].fz==true) reverse(x);
            int p=tr[x].son[1];
            if(tr[p].fz==true) reverse(p);
            while(tr[p].son[0]!=0)
            {
                p=tr[p].son[0];
                if(tr[p].fz==true) reverse(p);
            }
            splay(p,x);
            int r=tr[x].son[0],R=p;
            tr[R].son[0]=r;
            tr[r].f=R;
            rt=R;tr[R].f=0;
            update(R);
            tr[r].fz^=1;
        }
        len--;
    }
    int getmin()
    {
        int x=rt;
        while(tr[x].son[0]!=0||tr[x].son[1]!=0)
        {
            if(tr[x].fz==true) reverse(x);
            int lc=tr[x].son[0],rc=tr[x].son[1];
            int mmin=min(tr[x].d,min(tr[lc].mn,tr[rc].mn)),t=INF;
            if(tr[x].d==mmin) if(t>tr[x].p) t=tr[x].p;
            if(tr[lc].mn==mmin) if(t>tr[lc].mp) t=tr[lc].mp,x=lc;
            if(tr[rc].mn==mmin) if(t>tr[rc].mp) t=tr[rc].mp,x=rc;
            if(x!=lc&&x!=rc) break;
        }
        return x;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=2;i<=n+1;i++) scanf("%d",&a[i]);a[1]=a[n+2]=INF;
        len=0;rt=ins(1,n+2);
        for(int i=1;i<=n;i++)
        {
            int x=getmin();
            splay(x,0);
            if(i<n) printf("%d ",tr[tr[x].son[0]].c+i);
            else printf("%d
    ",tr[tr[x].son[0]].c+i);
            del(x);
        }
        return 0;
    }

     

  • 相关阅读:
    201771010125王瑜《面向对象程序设计(Java)》第十周学习总结
    201771010125王瑜《面向对象程序设计(Java)》第九周学习总结
    201771010125王瑜《面向对象程序设计(Java)》第八周学习总结
    7 Python外壳:代码结构
    6 python容器
    元组
    列表
    4 python基本元素之变量
    3 关于操作系统基本了解
    1 python是什么?
  • 原文地址:https://www.cnblogs.com/Never-mind/p/10154125.html
Copyright © 2020-2023  润新知