[Noi2005] 维修数列

1 篇文章 0 订阅

题目什么的大家都知道
艹你大爷的终于调过了。。。
傻逼的以为lazy=0就是没有修改了
闲话不说贴代码(真不知道该说什么)

#include <iostream> 
#include <cstdio> 
#include <algorithm> 
#include <cstdlib> 
#include <cstring> 
#include <string>
#include <algorithm>
#include <vector>
#include <deque>
#include <queue>
#include <map>
#include <set>
#include <ctime>
using namespace std;

const int MAXN=4000005,INF=1<<29;
int n,m,A[MAXN],root; 

int Get()
{ 
    char ch; int v=0; bool f=false;
    while (!isdigit(ch=getchar())) if (ch=='-') f=true; v=ch-48;
    while (isdigit(ch=getchar())) v=v*10+ch-48; 
    if (f) return -v;else return v; 
}

class Splay_Tree
{ 
    int tot,ch[MAXN][2],lazy[MAXN],fa[MAXN],size[MAXN],sum[MAXN],val[MAXN],_max[MAXN],lmax[MAXN],rmax[MAXN]; 
    bool rev[MAXN],tag[MAXN];

    void newnode(int v,int f,int type)
      { 
        tot++; if (f) ch[f][type]=tot; ch[tot][0]=ch[tot][1]=0; 
        val[tot]=sum[tot]=v,size[tot]=1,fa[tot]=f,lazy[tot]=0,rev[tot]=tag[tot]=false;
        if (v>=0) _max[tot]=lmax[tot]=rmax[tot]=v;else _max[tot]=v,lmax[tot]=rmax[tot]=0;
      }

    void modify(int x,int v) 
      { 
        if (x==0) return; 
        lazy[x]=val[x]=v,tag[x]=true,sum[x]=v*size[x]; 
        if (v>=0) _max[x]=lmax[x]=rmax[x]=sum[x];else _max[x]=v,lmax[x]=rmax[x]=0;
      }
    void rever(int x) { if (x==0) return; rev[x]^=1,swap(ch[x][0],ch[x][1]),swap(lmax[x],rmax[x]); } 

    void update(int x)
      { 
        if (x==0) return;
        int lc=ch[x][0],rc=ch[x][1]; 
        sum[x]=sum[lc]+sum[rc]+val[x],size[x]=size[lc]+size[rc]+1;
        _max[x]=max(rmax[lc]+val[x]+lmax[rc],max(_max[lc],_max[rc])); 
        lmax[x]=max(lmax[lc],sum[lc]+val[x]+lmax[rc]);
        rmax[x]=max(rmax[rc],sum[rc]+val[x]+rmax[lc]);
      } 

    void pushdown(int x)
      { 
        if (x==0) return; 
        int lc=ch[x][0],rc=ch[x][1];
        if (tag[x]) modify(lc,lazy[x]),modify(rc,lazy[x]),lazy[x]=0,tag[x]=false;
        if (rev[x]) rever(lc),rever(rc),rev[x]=false;
      }

    void maketree(int l,int r,int f,int type)
      {     
        if (l>r) return;
        int mid=(l+r)>>1; newnode(A[mid],f,type); int tmp=tot;
        maketree(l,mid-1,tmp,0),maketree(mid+1,r,tmp,1),update(tmp);
      }

    void Rotate(int x,int d)
      { 
        int y=fa[x],z=fa[y]; 
        ch[y][d^1]=ch[x][d],fa[ch[x][d]]=y,ch[x][d]=y,fa[y]=x; 
        if (z) ch[z][ch[z][1]==y]=x; fa[x]=z; 
        update(y); 
      }

    void splay(int x,int goal)
      {     
        if (!x) return; 
        pushdown(x); 
        while (fa[x]!=goal)
          {         
            int y=fa[x],z=fa[y];
            if (z==goal) Rotate(x,ch[y][0]==x);
            else 
              { 
                int f=(ch[y][1]==x);
                if (ch[z][f]==y) Rotate(y,f^1),Rotate(x,f^1);
                else Rotate(x,f^1),Rotate(x,f);
              }
          }
        update(x);
        if (!goal) root=x; 
      }

    int Find(int k)
      {      
        int x=root; pushdown(x);
        while (size[ch[x][0]]+1!=k)
          { 
            if (size[ch[x][0]]+1>k) x=ch[x][0];else k-=size[ch[x][0]]+1,x=ch[x][1];
            pushdown(x);  
          }
        return x; 
      } 

    int Select(int Ql,int Qr)
      { 
        int L=Find(Ql),R=Find(Qr+2);
        splay(L,0); splay(R,L);
        return ch[R][0]; 
      }

    public:

    void init()
      { 
        val[0]=sum[0]=_max[0]=lmax[0]=rmax[0]=size[0]=fa[0]=lazy[tot]=0,tag[0]=rev[0]=false,ch[0][0]=ch[0][1]=0;
        lmax[0]=rmax[0]=0,_max[0]=-INF; 
        newnode(-INF,0,0),newnode(-INF,1,1); root=1; size[1]=2;
      }

    void Insert(int pos,int cnt)
      { 
        for (int i=1;i<=cnt;i++) A[i]=Get(); 
        int keyx=Select(pos+1,pos); keyx=ch[root][1];
        maketree(1,cnt,keyx,0); update(keyx); splay(ch[keyx][0],0); 
      }

    void Delete(int pos,int cnt)
      {
        int keyx=Select(pos,pos+cnt-1); keyx=ch[root][1];
        ch[keyx][0]=0; update(keyx); splay(keyx,0);
      }

    void modify(int Ql,int Qr,int v)
      { 
        int keyx=Select(Ql,Qr);
        modify(keyx,v); splay(keyx,0);   
      }

    void rever(int Ql,int Qr)
      { 
        int keyx=Select(Ql,Qr);
        rever(keyx); splay(keyx,0);
      }

    void getsum(int Ql,int Qr)
      { 
        int keyx=Select(Ql,Qr);
        printf("%d\n",sum[keyx]); 
        splay(keyx,0);
      }

    void getmaxsum()
      { 
        printf("%d\n",_max[root]); 
      }

    /*void debug(int x)
      {  
        if (x==0) return;
        printf("No.%d fa=%d lc=%d rc=%d size=%d val=%d lazy=%d sum=%d _max=%d lmax=%d rmax=%d\n",x,fa[x],
        ch[x][0],ch[x][1],size[x],val[x],lazy[x],sum[x],_max[x],lmax[x],rmax[x]);
        debug(ch[x][0]); debug(ch[x][1]);
      }*/
}T;

int main() 
{ 
    //freopen("sequence.in","r",stdin);
    //freopen("sequence.out","w",stdout);
    n=Get(),m=Get(); T.init(); 
    T.Insert(0,n); char ch[21]; int pos,tot,v;
    while (m--)
      { 
        scanf(" %s",ch); 
        if (ch[0]=='I') pos=Get(),tot=Get(),T.Insert(pos,tot);
        if (ch[0]=='D') pos=Get(),tot=Get(),T.Delete(pos,tot);
        if (ch[0]=='R') pos=Get(),tot=Get(),T.rever(pos,pos+tot-1);
        if (ch[0]=='G') pos=Get(),tot=Get(),T.getsum(pos,pos+tot-1);
        if (ch[0]=='M') 
          { 
            if (ch[2]=='K') pos=Get(),tot=Get(),v=Get(),T.modify(pos,pos+tot-1,v);
            else T.getmaxsum();
          }
      } 
    return 0; 
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值