Looploop HDU - 4453

http://acm.hdu.edu.cn/showproblem.php?pid=4453

对一个循环序列进行操作 因为k1 k2都不会超过序列长度 所以指针不变时就是一些基本操作 当指针移动时可以当做区间交换 即进行三次区间翻转

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

struct node;
node *null;

struct node
{
    node *fa,*ch[2];
    int sz,rev,val,laz;
    void wipe()
    {
        fa=ch[0]=ch[1]=null;
        sz=1,val=0,laz=0,rev=0;
    }
    int getd()
    {
        return fa->ch[1]==this;
    }
    void setc(node *tmp,int d)
    {
        ch[d]=tmp;
        tmp->fa=this;
    }
    void add(int tlaz)
    {
        if(this==null) return;
        val+=tlaz,laz+=tlaz;
    }
    void reverse()
    {
        if(this==null) return;
        swap(ch[0],ch[1]);
        rev^=1;
    }
    void pushup()
    {
        sz=ch[0]->sz+ch[1]->sz+1;
    }
    void pushdown()
    {
        if(laz!=0)
        {
            ch[0]->add(laz);
            ch[1]->add(laz);
            laz=0;
        }
        if(rev!=0)
        {
            ch[0]->reverse();
            ch[1]->reverse();
            rev=0;
        }
    }
};

node pool[200010];
node *root,*tail;
int ary[100010];
int n,q,k1,k2,cnt;

void build(node *&cur,node *fa,int l,int r)
{
    int m;
    if(l>r) return;
    m=(l+r)/2;
    cur=tail++;
    cur->wipe();
    cur->fa=fa;
    cur->val=ary[m],cur->laz=0,cur->rev=0;
    build(cur->ch[0],cur,l,m-1);
    build(cur->ch[1],cur,m+1,r);
    cur->pushup();
}

void init()
{
    node *tmp;
    tail=pool;
    null=tail++;
    null->fa=null->ch[0]=null->ch[1]=null;
    null->sz=0,null->val=0,null->laz=0,null->rev=0;
    tmp=tail++;
    tmp->wipe();
    root=tmp;
    tmp=tail++;
    tmp->wipe();
    root->setc(tmp,1);
    build(root->ch[1]->ch[0],root->ch[1],1,n);
    root->ch[1]->pushup();
    root->pushup();
}

node *getkth(node *r,int k)
{
    node *cur;
    cur=r;
    cur->pushdown();
    while(cur->ch[0]->sz+1!=k)
    {
        if(cur->ch[0]->sz+1>k)
        {
            cur=cur->ch[0];
        }
        else
        {
            k-=(cur->ch[0]->sz+1);
            cur=cur->ch[1];
        }
        cur->pushdown();
    }
    return cur;
}

void rotate(node *cur)
{
    node *f,*ff;
    int c,cc;
    f=cur->fa,ff=cur->fa->fa;
    f->pushdown();
    cur->pushdown();
    c=cur->getd(),cc=f->getd();
    f->setc(cur->ch[!c],c);
    cur->setc(f,!c);
    if(ff->ch[cc]==f) ff->setc(cur,cc);
    else cur->fa=ff;
    f->pushup();
}

void splay(node *&root,node *tar,node *cur)
{
    while(cur->fa!=tar)
    {
        if(cur->fa->fa==tar) rotate(cur);
        else
        {
            cur->fa->fa->pushdown();
            cur->fa->pushdown();
            cur->pushdown();
            if(cur->getd()==cur->fa->getd()) rotate(cur->fa);
            else rotate(cur);
            rotate(cur);
        }
    }
    cur->pushup();
    if(tar==null) root=cur;
}

void insert(node *&cur,node *fa,int val)
{
    cur=tail++;
    cur->wipe();
    cur->fa=fa;
    cur->val=val,cur->laz=0,cur->rev=0;
}

void show()
{
    node *ptr;
    int i;
    printf("******\n");
    for(i=2;i<=cnt+1;i++)
    {
        ptr=getkth(root,i);
        printf("%d ",ptr->val);
    }
    printf("\n");
    printf("******\n\n\n");
}

int main()
{
    node *ptr;
    int cas,i,l,r,x;
    char op[10];
    cas=1;
    while(scanf("%d%d%d%d",&n,&q,&k1,&k2)!=EOF)
    {
        if(n==0&&q==0&&k1==0&&k2==0) break;
        cnt=n;
        for(i=1;i<=n;i++) scanf("%d",&ary[i]);
        init();
        printf("Case #%d:\n",cas++);
        scanf("%d",&q);
        while(q--)
        {
            scanf("%s",op);
            if(op[0]=='a')
            {
                scanf("%d",&x);
                splay(root,null,getkth(root,1));
                splay(root,root,getkth(root,k2+2));
                root->ch[1]->ch[0]->add(x);
                root->ch[1]->pushup();
                root->pushup();
            }
            else if(op[0]=='r')
            {
                splay(root,null,getkth(root,1));
                splay(root,root,getkth(root,k1+2));
                //printf("^%d %d^\n",getkth(root,1)->val,getkth(root,k1+1)->val);
                root->ch[1]->ch[0]->reverse();
                root->ch[1]->pushup();
                root->pushup();
            }
            else if(op[0]=='i')
            {
                cnt++;
                scanf("%d",&x);
                splay(root,null,getkth(root,2));
                splay(root,root,getkth(root,3));
                insert(root->ch[1]->ch[0],root->ch[1],x);
                root->ch[1]->pushup();
                root->pushup();
            }
            else if(op[0]=='d')
            {
                cnt--;
                splay(root,null,getkth(root,1));
                splay(root,root,getkth(root,3));
                root->ch[1]->ch[0]=null;
                root->ch[1]->pushup();
                root->pushup();
            }
            else if(op[0]=='m')
            {
                scanf("%d",&x);
                if(x==1)
                {
                    splay(root,null,getkth(root,1));
                    splay(root,root,getkth(root,cnt+2));
                    root->ch[1]->ch[0]->reverse();
                    root->ch[1]->pushup();
                    root->pushup();
                    //show();


                    splay(root,null,getkth(root,1));
                    splay(root,root,getkth(root,3));
                    root->ch[1]->ch[0]->reverse();
                    root->ch[1]->pushup();
                    root->pushup();
                    //show();


                    splay(root,null,getkth(root,2));
                    splay(root,root,getkth(root,cnt+2));
                    root->ch[1]->ch[0]->reverse();
                    root->ch[1]->pushup();
                    root->pushup();
                    //show();
                }
                else
                {
                    splay(root,null,getkth(root,1));
                    splay(root,root,getkth(root,cnt+2));
                    root->ch[1]->ch[0]->reverse();
                    root->ch[1]->pushup();
                    root->pushup();

                    splay(root,null,getkth(root,1));
                    splay(root,root,getkth(root,cnt+1));
                    root->ch[1]->ch[0]->reverse();
                    root->ch[1]->pushup();
                    root->pushup();

                    splay(root,null,getkth(root,cnt));
                    splay(root,root,getkth(root,cnt+2));
                    root->ch[1]->ch[0]->reverse();
                    root->ch[1]->pushup();
                    root->pushup();

                }
            }
            else
            {
                ptr=getkth(root,2);
                printf("%d\n",ptr->val);
            }
            //show();
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值