zoukankan      html  css  js  c++  java
  • Codevs1743--反转卡片

    在Splay上打反转标记

    自己脑补了一下,感觉就是在旋转的时候传递一下标记免得被破坏就可以了。

    具体交换左右儿子然后标记下传。

    代码:

    #include<bits/stdc++.h>
    #define MAXN 300005
    #define MAXM 3005
    #define INF 1000000000
    #define MOD 1000000
    #define LL long long
    using namespace std;
    
    int n;
    
    namespace Splay{
        const int L=0,R=1;
        int root;
        struct Node{
            int son[2],v,sz,par;
            bool turn;
        }x[MAXN];
        
        inline void Push_down(int num) {
            swap(x[num].son[L],x[num].son[R]);x[num].turn^=1;
            x[x[num].son[L]].turn^=1;x[x[num].son[R]].turn^=1;
        }
        inline void rotate(int num,int p) {
            int pa=x[num].par,t=x[num].sz;
            if(x[pa].par) x[x[pa].par].son[x[x[pa].par].son[L]==pa?L:R]=num;
            x[num].sz=x[pa].sz;x[pa].sz-=t-x[x[num].son[p]].sz;
            x[pa].son[p^1]=x[num].son[p];if(x[num].son[p]) {x[x[num].son[p]].par=pa;}
            x[num].son[p]=pa;x[num].par=x[pa].par;x[pa].par=num;
        }
        inline void Splay_N(int num,int gl) {
            int par,ppar;
            while(x[num].par!=gl) {
                if(x[x[x[num].par].par].turn) Push_down(x[x[num].par].par);
                if(x[x[num].par].turn) Push_down(x[num].par);if(x[num].turn) Push_down(num);
                if(x[x[num].par].par==gl) {rotate(num,x[x[num].par].son[L]==num?R:L);break;}
                par=x[x[num].par].son[L]==num?R:L;ppar=x[x[x[num].par].par].son[L]==x[num].par?R:L;
                if(par==ppar) rotate(x[num].par,ppar),rotate(num,par);
                else rotate(num,par),rotate(num,ppar);
            }
            if(!gl) root=num;
        }
        
        int Build_Splay(int l,int r,int fr) {
            if(r<l) return 0;
            int mid=l+r>>1;x[mid].par=fr;
            if(l==r) {x[mid].sz=1;return mid;}
            x[mid].son[L]=Build_Splay(l,mid-1,mid);
            x[mid].son[R]=Build_Splay(mid+1,r,mid);
            x[mid].sz=x[x[mid].son[L]].sz+x[x[mid].son[R]].sz+1;
            return mid;
        }
        void Build() {root=Build_Splay(1,n+1,0);}
        
        int Qurey(int k) {
            int now=root;
            while(true) {
                if(x[now].turn) k=x[now].sz-k+1;
                if(x[x[now].son[L]].sz==k-1) {Splay_N(now,0);return now;}
                if(x[x[now].son[L]].sz<k) {k-=x[x[now].son[L]].sz+1;now=x[now].son[R];}
                else now=x[now].son[L];
            }
        }
        void Turn(int k) {
            Splay_N(Qurey(k),0);
            x[x[root].son[L]].turn^=1;
        }
        bool Check() {
            int t=Qurey(1);t=x[t].v;
            if(t==1) return 0;
            Turn(1+t);
            /*for(int i=1;i<=n;i++) cout<<x[Qurey(i)].v<<" ";
            cout<<endl;*/
            return 1;
        }
    }
    
    using namespace Splay;
    int main() {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            scanf("%d",&x[i].v);
        }
        Build();
        for(int i=1;i<=100000;i++) {
            if(!Check()) {printf("%d
    ",i-1);break;}
        }
        return 0;
    }
  • 相关阅读:
    『C#基础』C#读写TXT文档
    『ExtJS』给 Panel Items 中的 Grid 更新数据
    『Spring.NET』常见错误整理(持续更新)
    『WPF』Timer的使用
    『WPF』使用 [Annotation] 注释来定制数据/实体类
    『WPF』DataGrid的使用
    vbs修改注册表
    利用C#重启远程计算机
    sql server2000创建表和修改表
    存储过程得到某个表的所有字段信息
  • 原文地址:https://www.cnblogs.com/ihopenot/p/5919813.html
Copyright © 2011-2022 走看看