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;
        }
    }
  • 相关阅读:
    【Todo】各种语言里面的for循环 & loop
    git/icode操作记录
    UVA 639 (13.08.25)
    TkinterGUI
    [置顶] think in java interview-高级开发人员面试宝典(七)
    通过memcached来实现对tomcat集群中Session的共享策略
    Hibernate 配置详解(7)
    python模块之bsddb: bdb高性能嵌入式数据库 1.基础知识
    Python基础
    Objective-C中NSArray和NSMutableArray的基本用法
  • 原文地址:https://www.cnblogs.com/orzzz/p/8186026.html
Copyright © 2011-2022 走看看