zoukankan      html  css  js  c++  java
  • uva11922splay

    题意:一个值1到n的数组,一种(多次)操作把l到r的区间反转,然后放到数组尾部

    题解:裸的splay,用区间合并和区间分割,反转用lazy标记+pushdown就好了

    #include<bits/stdc++.h>
    #include<ext/rope>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    using namespace __gnu_cxx;
    
    const double g=10.0,eps=1e-7;
    const int N=100000+10,maxn=1000000+10,inf=0x3f3f3f;
    
    struct Node{
        Node* ch[2];
        int v;
        int s;
        int flip;
        int cmp(int x)const{
            int d = x - ch[0]->s;
            if(d==1)return -1;
            return d<=0 ? 0:1;
        }
        void maintain()
        {
            s = 1 + ch[0]->s + ch[1]->s;
        }
        void pushdown()
        {
            if(flip)//类似于线段树的lazy标记
            {
                flip=0;
                swap(ch[0],ch[1]);
                ch[0]->flip = !(ch[0]->flip);
                ch[1]->flip = !(ch[1]->flip);
            }
        }
    };
    Node* null = new Node();
    void Rotate(Node* &o,int d)
    {
        Node* k = o->ch[d^1];
        o->ch[d^1] = k->ch[d];
        k->ch[d] = o;
        o->maintain();k->maintain();
        o = k;
    }
    void splay(Node* &o,int k)
    {
        o->pushdown();
        int d = o->cmp(k);
        if(d==1)k -= o->ch[0]->s + 1;//利用二叉树性质
        if(d!=-1)
        {
            Node* p = o->ch[d];
            p->pushdown();
            int d2 = p->cmp(k);
            int k2 = (d2==0 ? k:k-p->ch[0]->s-1);
            if(d2!=-1)
            {
                splay(p->ch[d2],k2);
                if(d==d2)Rotate(o,d^1);
                else Rotate(o->ch[d],d);
            }
            Rotate(o,d^1);
        }
    }
    Node* Merge(Node* left,Node* right)
    {
        splay(left,left->s);//把排名最大的数splay到根
        left->ch[1] = right;
        left->maintain();
        return left;
    }
    void split(Node* o,int k,Node* &left,Node* &right)
    {
        splay(o,k);//把排名为k的节点splay到根,右侧子树所有节点排名比k大,左侧小
        right = o->ch[1];
        o->ch[1] = null;
        left = o;
        left->maintain();
    }
    struct SplayTree{
        int n;
        Node seq[N];
        Node* root;
        Node* build(int sz)
        {
            if(sz==0)return null;
            Node* l=build(sz/2);
            Node* o=&seq[++n];
            o->v=n;
            o->ch[0]=l;
            o->ch[1]=build(sz-sz/2-1);
            o->s = o->flip = 0;
            o->maintain();
            return o;
        }
        void init(int sz)
        {
            n=0;
            null->s = 0;
            root = build(sz);
        }
    };
    vector<int>ans;
    void print(Node* o)
    {
        if(o!=null)
        {
            o->pushdown();
            print(o->ch[0]);
            ans.pb(o->v);
            print(o->ch[1]);
        }
    }
    void debug(Node* o)
    {
        if(o!=null)
        {
            o->pushdown();
            debug(o->ch[0]);
            cout<<o->v<<endl;
            debug(o->ch[1]);
        }
    }
    SplayTree ss;
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        ss.init(n+1);
      //  debug(ss.root);
        while(m--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            Node *o,*left,*mid,*right;
            split(ss.root,a,left,o);//把ab整体右移一位,保证不会出现0
            split(o,b-a+1,mid,right);
            mid->flip^=1;
            //把left+mid+right变成left+right+mid(fliped)
            ss.root = Merge(Merge(left,right),mid);
        }
        print(ss.root);
        for(int i=1;i<ans.size();i++)
            printf("%d
    ",ans[i]-1);
        return 0;
    }
    /************
    
    ************/
    View Code
  • 相关阅读:
    野指针防范
    Linuxgate.so.1的含义[ZZ]
    malloc hook
    用PDF补丁丁一分钟批量删除PDF文档的第一页和最后一页
    PDF 补丁丁 0.4 测试版已经上线
    生活小百科:实用的生活保健小窍门,60则!....
    Pascal Analyzer 4 代码分析使用简要说明
    大数法则
    make: *** No rule to make target `all'. Stop.
    界面动态配置:持久化反持久化
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7748488.html
Copyright © 2011-2022 走看看