zoukankan      html  css  js  c++  java
  • 非旋Treap——维护数列

    https://www.luogu.org/problemnew/show/P3391

    知识点:1.split:1.拆数值 2.拆排名

        2.merge

        3.截取l - r这个区间,先截l - 1出来,再截 r - l +1(是r-l+1而不是r)

    code:

    #include <bits/stdc++.h>
    #define M 500002
    using namespace std;
    int n,m,root;
    int tot = 0;
    int lazy[M];
    int head[M],cnt;
    struct edge
    {
        int to;
        int nxt;
    }e[M * 2];
    void add(int x,int y)
    {
        e[++cnt].nxt = head[x];
        e[cnt].to = y;
        head[x] = cnt;
    }
    int siz[M];
    int ch[M][2],val[M],rd[M];
    void updata(int x)
    {
        siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
    }
    int newnode(int x)
    {
        val[++tot] = x;
        rd[tot] = rand();
        siz[tot] = 1;
        return tot;
    } 
    void down(int x)
    {
        swap(ch[x][0],ch[x][1]);
        if(ch[x][0]) lazy[ch[x][0]] ^= 1;
        if(ch[x][1]) lazy[ch[x][1]] ^= 1;
        lazy[x] = 0;
    }
    void split(int now,int k,int &x,int &y)
    {
        if(!now)
        {
            x = y = 0;
            return;
        }
        else
        {
            if(lazy[now])down(now);
            if(siz[ch[now][0]] < k)
            {
                x = now;
                split(ch[now][1],k - siz[ch[now][0]] - 1,ch[now][1],y);
            }
            else
            {
                y = now;
                split(ch[now][0],k,x,ch[now][0]);
            }
            updata(now);
        }
    }
    int merge(int A,int B)
    {
        if(!A || !B)return A + B;
        if(rd[A] < rd[B])
        {
            if(lazy[A])down(A);
            ch[A][1] = merge(ch[A][1],B);
            updata(A);
            return A;   
        } 
        else
        {
            if(lazy[B])down(B);
            ch[B][0] = merge(A,ch[B][0]);
            updata(B);
            return B;
        }
    }
    void work(int x,int y)
    {
        int a,b,c,d; 
        split(root,x - 1,a,b);
        split(b,y - x + 1,b,c);
        lazy[b] ^= 1;
        root = merge(a,merge(b,c));
    }
    void insert(int t)
    {
        root = merge(root,newnode(t));
    }
    void print(int i)
    {
        if(!i) return;
        if(lazy[i]) down(i);
        print(ch[i][0]);
        printf("%d ",val[i]);
        print(ch[i][1]);
    }
    int main()
    {
        srand(1);
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++)insert(i);
        int x,y;
        while(m--)
        {
            scanf("%d%d",&x,&y);
            work(x,y);
        }
        print(root);
        return 0;
    }
  • 相关阅读:
    组策略导入导出secedit
    ipad常见错误
    ipad系统路径
    内核操作注册表例子
    WoW64子系统
    win2003 shutdown命令
    regedit 导入注册表
    windbg for CLR
    WM_POWERBROADCAST
    OpenSSL命令
  • 原文地址:https://www.cnblogs.com/xyj1/p/10943407.html
Copyright © 2011-2022 走看看