bzoj1500[NOI2005]维修数列

一直心心念念着的splay模板。终于写了。

写了半个下午,然后半个晚上重构,半个晚上debug。

终于A了。。

码力真是弱的可怕。

二十分钟找到第一个bug,kth时忘了down。

然后剩下的一整个晚上才发现第2个bug,且是在同一个地方,应该是先down再判断找没找到。

又花了十分钟找到第三个bug,先del再把它设为0,都为0了还del个鬼啊。。。

以前写不出题基本上上都是完全没思路,然后现在完全没思路的多,还常碰到有想法但写不出来或者写起来非常难受的,码力真的需要提升啊,智商已经低了,码力还这么低岂不是药丸。

唯一一点欣慰是一开始写了近300慢慢改到了不到200。

只是今天学数学的目标又泡汤了。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cmath>
const int N=500007;
typedef long long LL;
using namespace std;
int root,n,a[N],m;
char op[20];

template<typename T>void read(T &x) {
    char ch=getchar(); T f=1; x=0;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

queue<int>que;
int v[N],sz[N],flip[N],lz[N],lzz[N],p[N],ch[N][2],ll[N],rr[N],mm[N],sum[N];

#define lc ch[x][0]
#define rc ch[x][1]
int ins() {int x=que.front(); que.pop(); return x;}
void del(int x) {
    if(lc) del(lc);
    lz[x]=flip[x]=0;
    que.push(x); 
    if(rc) del(rc);
}

void schange(int x,int vv) {
    v[x]=lzz[x]=vv; 
    lz[x]=1; flip[x]=0;
    sum[x]=sz[x]*vv;
    if(vv>=0) ll[x]=rr[x]=mm[x]=sum[x];    
    else ll[x]=rr[x]=0,mm[x]=vv;
}

void rever(int x) {
    swap(ll[x],rr[x]);
    flip[x]^=1;
}

void update(int x) {
    sz[x]=sz[lc]+sz[rc]+1;
    sum[x]=sum[lc]+sum[rc]+v[x];
    ll[x]=max(ll[lc],sum[lc]+v[x]+ll[rc]);
    rr[x]=max(rr[rc],sum[rc]+v[x]+rr[lc]);
    mm[x]=rr[lc]+v[x]+ll[rc];
    if(lc) mm[x]=max(mm[lc],mm[x]);
    if(rc) mm[x]=max(mm[rc],mm[x]);
}

void down(int x) {
    if(lz[x]) {
        if(lc) schange(lc,lzz[x]);
        if(rc) schange(rc,lzz[x]);
        lz[x]=0;
    } 
    if(flip[x]) {
        if(lc) rever(lc);
        if(rc) rever(rc);
        swap(lc,rc);
        flip[x]=0;
    }
}

void rotate(int x) {
    int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1;
    if(z) ch[z][y==ch[z][1]]=x; p[x]=z;    
    ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
    ch[x][r]=y; p[y]=x;
    update(y); update(x);
}

void splay(int x,int FA) {
    static int g[N],top=0,tp;
    for(tp=x;tp!=FA;tp=p[tp]) g[++top]=tp;
    while(top) down(g[top--]);
    for(;p[x]!=FA;rotate(x)) {
        int y=p[x],z=p[y];
        if(z!=FA) 
            ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y);
    }
    if(!FA) root=x;
}

int build(int l,int r) {
    if(l>r) return 0;
    int mid=((l+r)>>1);
    int x=ins(); v[x]=a[mid];
    lc=build(l,mid-1); if(lc) p[lc]=x;
    rc=build(mid+1,r); if(rc) p[rc]=x;
    update(x);
    return x;
}

int kth(int k) {
    for(int x=root;x;) {
        down(x);
        if(sz[lc]+1==k) return x;
        if(sz[lc]+1<k) k-=(sz[lc]+1),x=rc;
        else x=lc;
    }
}

void insert(int pos) {
    if(!n) return;
    int z=build(1,n);
    if(!root) root=z,p[z]=0;
    else if(pos==0) {
        int x=kth(1);
        splay(x,0); p[z]=x;
        lc=z; update(x);
    }
    else if(pos==sz[root]) {
        int x=kth(sz[root]);
        splay(x,0); p[z]=x;
        rc=z; update(x);
    }
    else {
        int x=kth(pos);
        splay(x,0);
        x=kth(pos+1);
        splay(x,root); p[z]=x;
        lc=z; update(x);
        update(root);
    }
}

int split(int pos,int &fa,int o) {
    if(pos==1&&sz[root]==n) {
        if(o) {del(root); root=0; }
        return root;
    }
    if(pos==1) {
        int x=kth(pos+n);
        splay(x,0);
        if(o) {del(lc); lc=0; update(x);} 
        return lc;    
    }
    else if(pos+n-1==sz[root]){
        int x=kth(pos-1);
        splay(x,0);
        if(o) {del(rc); rc=0;  update(x);}
        return rc;
    }
    else {
        int x=kth(pos-1); splay(x,0);
        x=kth(pos+n); splay(x,root);
        if(o) {del(lc); lc=0; update(x); update(root);}
        fa=x; return lc;
    }
}

int main() {
    read(n);
    read(m);
    for(int i=1;i<N;i++) { que.push(i); sz[i]=1;}
    for(int i=1;i<=n;i++) read(a[i]);
    root=build(1,n);
    while(m--) {
        int pos,c,x,fa=0;
        int szzz=que.size();
        scanf("%s",op);
        if(op[2]!='X') {
            read(pos); read(n);
        } 
        if(op[0]=='I') {
            for(int i=1;i<=n;i++) read(a[i]);
            insert(pos);
        }
        else if(op[0]=='D') x=split(pos,fa,1);
        else if(op[2]=='K') {
            read(c);
            x=split(pos,fa,0);
            schange(x,c); 
            if(fa) update(fa);
            update(root);
        }
        else if(op[0]=='R') {
            x=split(pos,fa,0);
            rever(x); 
            if(fa) update(fa);
            update(root);
        }
        else if(op[0]=='G') {
            x=split(pos,fa,0);
            printf("%d\n",sum[x]);
        }
        else printf("%d\n",mm[root]);
    }
    return 0;
}
View Code

 

posted @ 2017-12-20 22:03  啊宸  阅读(134)  评论(0编辑  收藏  举报