BZOJ 1500 【NOI2005 D1T2】 维修数列 Splay

来源:互联网 发布:max守望先锋数据异常 编辑:程序博客网 时间:2024/05/18 01:53

题目大意:维护一个数列支持以下操作:
这里写图片描述

这个Splay有毒,抄模板请参照这里

Splay裸题
可啪(?)的题,细节真的很重要
parent指针好像乱七八糟的样子,但是没用上…
在maintain操作前要先pushdown把标记推下去(标记也修改自己,不推标记的话不能保证信息的正确性)
子段和也要用自己的权值去更新

这俩错误查一天…

#include <cstdio>#include <algorithm>#define INF 500000001#define Max(a,b) (a>b?a:b)using namespace std;int n,m,a[500005];struct Node{    Node *ch[2],*pa;    int v,s,lmax,rmax,sum,maxs,fix;    bool flip,change;    Node(int);    int cmp(int x){        if(x==ch[0]->s+1) return -1;        return x < ch[0]->s+1 ? 0 : 1;    }    void maintain();    void pushdown();}*null,*root;void Node :: maintain(){    ch[0]->pushdown(); ch[1]->pushdown();    s=ch[0]->s+ch[1]->s+1;    sum=ch[0]->sum+ch[1]->sum+v;    lmax=Max(ch[0]->lmax,ch[0]->sum+v); lmax=Max(lmax,ch[0]->sum+v+ch[1]->lmax);    rmax=Max(ch[1]->rmax,ch[1]->sum+v); rmax=Max(rmax,ch[1]->sum+v+ch[0]->rmax);    maxs=Max(ch[0]->maxs,ch[1]->maxs); maxs=Max(maxs,v);    maxs=Max(ch[0]->rmax+v,maxs); maxs=Max(ch[1]->lmax+v,maxs); maxs=Max(ch[0]->rmax+v+ch[1]->lmax,maxs);    return ;}void Node :: pushdown(){    if(this==null) return ;    if(change){        change=false;        ch[0]->change=ch[1]->change=true;        ch[0]->fix=ch[1]->fix=fix;        sum=s*fix;        v=fix;        if(fix>0)lmax=rmax=maxs=sum;        else lmax=rmax=maxs=fix;    }    if(flip){        flip=false;        swap(ch[0],ch[1]);        swap(lmax,rmax);        ch[0]->flip=!ch[0]->flip;        ch[1]->flip=!ch[1]->flip;    }    return ;}Node :: Node(int v=0):v(v){    pa=ch[0]=ch[1]=null; flip=change=false;    if(!null){        lmax=rmax=maxs=-INF;        sum=0;        s=0;    }    else maintain();}void init(Node*& o,int l,int r){    int mid=(l+r)>>1;    if(l>r){        o=null;        return ;    }    o=new Node(a[mid]);    init(o->ch[0],l,mid-1); init(o->ch[1],mid+1,r);    if(o->ch[0]!=null) o->ch[0]->pa=o;    if(o->ch[1]!=null) o->ch[1]->pa=o;    o->maintain();    return ;}void Rotate(Node*& o,int d){    Node* k=o->ch[d^1];    o->ch[d^1]=k->ch[d]; k->ch[d]->pa=o;    k->ch[d]=o; k->pa=o->pa; o->pa=k;    o->maintain(); k->maintain();    o=k;    return ;}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);        if(d2==1) k-=p->ch[0]->s+1;        if(d2!=-1){            Splay(p->ch[d2],k);            if(d==d2) Rotate(o,d^1);            else Rotate(o->ch[d],d);        }        Rotate(o,d^1);    }    return ;}Node* Merge(Node* l,Node* r){    if(l==null) return r;    Splay(l,l->s);    l->ch[1]=r;    r->pa=l;    l->maintain();    return l;}void Split(Node* o,int k,Node*& l,Node*& r){    if(!k){        l=null;        r=o;        return ;    }    Splay(o,k);    l=o;    r=o->ch[1];    o->ch[1]=null;    l->maintain();    return ;}void Delete(Node*& o){    if(o->ch[0]!=null) Delete(o->ch[0]);    if(o->ch[1]!=null) Delete(o->ch[1]);    delete o;    o=null;    return ;}int main(){    freopen("a.in","r",stdin); freopen("a.out","w",stdout);    null=new Node();    null->ch[0]=null->ch[1]=null->pa=null;    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++) scanf("%d",&a[i]);    init(root,1,n);    while(m--){        char c[10];        scanf("%s",c);        if(c[0]=='I'){//Insert            int pos,tot;            scanf("%d%d",&pos,&tot);            for(int i=1;i<=tot;i++) scanf("%d",&a[i]);            Node *o,*l,*r;            init(o,1,tot);            Split(root,pos,l,r);            root=Merge(Merge(l,o),r);        }        else if(c[0]=='D'){//Delete            int pos,tot;            scanf("%d%d",&pos,&tot);            Node *mid,*l,*r,*o;            Split(root,pos-1,l,o);            Split(o,tot,mid,r);            Delete(mid);            root=Merge(l,r);        }        else if(c[0]=='R'){//Reverse            int pos,tot;            scanf("%d%d",&pos,&tot);            Node *mid,*l,*r,*o;            Split(root,pos-1,l,o);            Split(o,tot,mid,r);            mid->flip=true;            root=Merge(Merge(l,mid),r);        }        else if(c[0]=='G'){//GET-SUM            int pos,tot;            scanf("%d%d",&pos,&tot);            if(!tot){                printf("0\n");                continue;            }            Node *mid,*l,*r,*o;            Split(root,pos-1,l,o);            Split(o,tot,mid,r);            printf("%d\n",mid->sum);            root=Merge(Merge(l,mid),r);        }        else if(c[2]=='X'){//MAX-SUM            printf("%d\n",root->maxs);        }        else {//MAKE-SAME            int pos,tot,cach;            scanf("%d%d%d",&pos,&tot,&cach);            Node *mid,*l,*r,*o;            Split(root,pos-1,l,o);            Split(o,tot,mid,r);            mid->change=true;            mid->fix=cach;            root=Merge(Merge(l,mid),r);        }    }    return 0;}
0 0
原创粉丝点击