zoukankan      html  css  js  c++  java
  • [bzoj1552][Cerc2007]robotic sort&&[bzoj3506][Cqoi2014]排序机械臂

    非常垃圾的一道平衡树,结果被日了一天。很难受嗷嗷嗷

    首先不得不说网上的题解让我这个本来就不熟悉平衡树的彩笔很难受——并不好理解。

    还好Sinogi大佬非常的神,一眼就切掉了,而且用更加美妙的解法。

    题意在操作时,就是第i次把编号为i-1和编号i的后继分别提到根和根的右儿子,根的右儿子的左子树打上翻转标记。

    用外部数组记录原来高度第几大的在平衡树中编号是多少。就可以直接操作了。

    注意有相同的高度,离散化时直接按高度第一关键字,编号第二关键字就行了。

    还有每次splay要把根到当前节点都pushdown一遍。还有先pushdown再继续操作!包括判断有没有左右儿子!

    可能只有我是傻逼吧

    #include<bits/stdc++.h>
    using namespace std;
    const int N=200010;
    inline int read(){
        int r=0,c=getchar();
        while(!isdigit(c))c=getchar();
        while(isdigit(c))
        r=r*10+c-'0',c=getchar();
        return r;
    }
    #define ls ch[x][0]
    #define rs ch[x][1]
    int ch[N][2],siz[N],fa[N],rev[N],pos[N];
    int rt,tot;
    struct qwq{
        int v,p;
    }a[N];
    bool cmpv(qwq p,qwq q){
        if(p.v==q.v)return p.p<q.p;
        return p.v<q.v;
    }
    bool cmpp(qwq p,qwq q){
        return p.p<q.p;
    }
    void pp(int x){
        siz[x]=siz[ls]+siz[rs]+1;
    }
    void pd(int x){
        if(rev[x]){
            rev[x]=0;
            swap(ls,rs);
            rev[ls]^=1;rev[rs]^=1;
        }
    }
    int get(int x){
        return x==ch[fa[x]][1];
    }
    void rotate(int x){
        int y=fa[x],z=fa[y],px=get(x),py=get(y);
        int t=ch[x][px^1];
        ch[x][px^1]=y;fa[y]=x;
        ch[y][px]=t;fa[t]=y;
        if(z)ch[z][py]=x;fa[x]=z;
        pp(y);
    }
    int s[N];
    void splay(int x,int lim){
        int top=0;
        for(int i=x;i;i=fa[i])s[++top]=i;
        for(int i=top;i;i--)pd(s[i]);
        int y=fa[x];
        while(y^lim){
            if(fa[y]^lim)
            rotate(get(x)==get(y)?y:x);
            rotate(x);y=fa[x];
        }
        rt=!lim?x:rt;pp(x);
    }
    int nxt(){
        pd(rt);int x=ch[rt][1];
        while(pd(x),ch[x][0])x=ch[x][0];
        return x;
    }
    int build(int l,int r){
        if(l>r)return 0;
        int mid=l+r>>1,x=++tot;
        ls=build(l,mid-1);fa[ls]=x;
        rs=build(mid+1,r);fa[rs]=x;
        pos[a[mid].v]=x;
        pp(x);return x;
    }
    int main(){
        int n=read();
        a[1].v=0,a[n+2].v=n+1;
        for(int i=2;i<=n+1;i++)
        a[i].v=read(),a[i].p=i;
        sort(a+2,a+n+2,cmpv);
        for(int i=2;i<=n+1;i++)
        a[i].v=i-1;
        sort(a+2,a+n+2,cmpp);
        rt=build(1,n+2);
        for(int i=1;i<=n;i++){
            int x=pos[i];splay(x,0);
            printf("%d",siz[ls]);if(i^n)printf(" ");
            x=nxt();
            int y=pos[i-1];
            splay(y,0);splay(x,rt);
            rev[ls]^=1;
        }
    }
  • 相关阅读:
    mac 切换 默认xcode 版本
    mac 查看jenkins 管理员密码地址
    解决 mac ox 终端显示bogon 的问题
    eclipse 修改默认作者信息
    mac 查看 本地网络代理
    appium 解决 启动case 时不 重装 setting 和 unlock.apk的解决方案实践
    appium 输入时间慢的解决方案
    命令 关闭 appium 命令
    解决 appium could not start ios-webkit-debug-proxy
    PPT总结
  • 原文地址:https://www.cnblogs.com/orzzz/p/8186026.html
Copyright © 2011-2022 走看看