码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1890 Robotic Sort 伸展树的区间反转与延迟标记

时间:2014-06-05 08:33:14      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:c   style   class   blog   code   a   

延迟标记像极了线段树,不再多说。

区间反转在树伸展到位之后,也变成了简单的递归交换左右儿子。

愈发感觉到伸展树简直太漂亮了,伸展操作更是诱惑到不行 ,总之数据结构太有魅力了。

比较简单,就直接上模板了。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>

#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 9999991

using namespace std;

const int MAXN = 100100;

struct N
{
    //info
    int son[2],pre,data;

    //data
    bool mark;
    int ls,rs,s;
} st[MAXN];

int Top;

struct W
{
    int data,site;
} num[MAXN],tnum[MAXN];

bool cmp(W a1,W a2)
{
    if(a1.data < a2.data)
        return true;
    if(a1.data == a2.data && a1.site < a2.site)
        return true;
    return false;
}

void Push_Down(int root)
{
    if(st[root].mark == 1)
    {
        st[root].mark = 0;
        if(st[root].son[0] != -1)
            st[st[root].son[0]].mark ^= 1;
        if(st[root].son[1] != -1)
            st[st[root].son[1]].mark ^= 1;

        int temp;
        temp = st[root].son[0];
        st[root].son[0] = st[root].son[1];
        st[root].son[1] = temp;

        temp = st[root].ls;
        st[root].ls = st[root].rs;
        st[root].rs = temp;
    }
}

void Updata(int root)
{
    st[root].ls = st[root].son[0] == -1 ? 0 : st[st[root].son[0]].s;
    st[root].rs = st[root].son[1] == -1 ? 0 : st[st[root].son[1]].s;
    st[root].s = st[root].ls + st[root].rs + 1;
}

void Init(int &root,int s,int e,int pre)
{
    if(s > e)
        return ;
    int mid = (s+e)>>1;

    root = Top++;
    st[root].son[0] = -1;
    st[root].son[1] = -1;
    st[root].pre = pre;
    st[root].data = num[mid].data;
    st[root].mark = 0;
    num[mid].site = root;

    Init(st[root].son[0],s,mid-1,root);
    Init(st[root].son[1],mid+1,e,root);

    Updata(root);
}

void Rotate(int root,int dir)
{
    st[st[root].pre].son[dir] = st[root].son[1^dir];
    st[root].son[1^dir] = st[root].pre;

    if(st[st[st[root].pre].pre].son[0] == st[root].pre)
        st[st[st[root].pre].pre].son[0] = root;
    else
        st[st[st[root].pre].pre].son[1] = root;
    int temp = st[root].pre;
    st[root].pre = st[st[root].pre].pre;
    st[temp].pre = root;

    if(st[temp].son[dir] != -1)
        st[st[temp].son[dir]].pre = temp;
    Updata(temp);
    Updata(root);
}

void Updata_Lazy(int root,int goal)
{
    if(st[root].pre != goal)
    {
        Updata_Lazy(st[root].pre,goal);
    }

    Push_Down(root);
}

int Splay(int root,int goal)
{
    Updata_Lazy(root,goal);

    while(st[root].pre != goal)
    {
        Rotate(root,(st[st[root].pre].son[0] == root ? 0 : 1));
    }

    return root;
}

int Search_Site(int root,int site)
{
    do
    {
        Push_Down(root);

        if(st[root].ls + 1 == site)
            return root;
        if(st[root].ls + 1 < site)
        {
            site = site - st[root].ls - 1;
            root = st[root].son[1];
        }
        else
            root = st[root].son[0];
    }while(1);
}


int main()
{
    int n;

    int i;

    int root,lsite,rsite;

    while(scanf("%d",&n) && n)
    {
        for(i = 2; i <= n+1; ++i)
        {
            scanf("%d",&tnum[i].data);
            num[i].site = i;
            tnum[i].site = i;
        }

        sort(tnum+2,tnum+n+2,cmp);

        num[1].data = 1,num[1].site = 1;
        num[n+2].data = n+2,num[n+2].site = n+2;

        for(i = 2; i <= n+1; ++i)
        {
            num[tnum[i].site].data = i;
        }

        root = -1,Top = 1;

        Init(root,1,n+2,0);

        st[0].son[0] = root,st[0].son[1] = -1;//虚拟父节点

        for(i = 2; i <= n+1; ++i)
        {
            root = Splay(num[tnum[i].site].site,0);

            printf("%d",st[root].ls);
            if(i == n+1) printf("\n");
            else printf(" ");

            lsite = min(st[root].ls+1,num[tnum[i].site].data)-1;
            rsite = max(st[root].ls+1,num[tnum[i].site].data)+1;
            lsite = Search_Site(root,lsite);
            rsite = Search_Site(root,rsite);
            root = Splay(rsite,0);
            root = Splay(lsite,0);
            st[st[st[root].son[1]].son[0]].mark ^= 1;
        }

    }
    return 0;
}

HDU 1890 Robotic Sort 伸展树的区间反转与延迟标记,布布扣,bubuko.com

HDU 1890 Robotic Sort 伸展树的区间反转与延迟标记

标签:c   style   class   blog   code   a   

原文地址:http://blog.csdn.net/zmx354/article/details/27371603

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!