zoukankan      html  css  js  c++  java
  • 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;
    }

     

  • 相关阅读:
    Web前端基础(1):HTML(一)
    python基础(35):协程
    python基础(34):线程(二)
    python基础(33):线程(一)
    python基础(32):进程(二)
    python基础(31):进程(一)
    python基础(30):黏包、socket的其他方法
    用keychain这个特点来保存设备唯一标识。
    判断iPhone的WiFi是否打开的两种方法 之是否连接上 WiFi
    NSStringCompareOptions
  • 原文地址:https://www.cnblogs.com/Never-mind/p/10154125.html
Copyright © 2011-2022 走看看