[BZOJ1500]维修数列 Treap

兄弟千万别写非旋Treap
卡常卡得飞起
10s+1s跑过去

#include 
#define INF (1<<30)
#define N 500050

#define L tr[ tr[t].ls ]
#define R tr[ tr[t].rs ]
#define O tr[t]

using namespace std;
typedef pair<int,int> pii;
#define MP make_pair
struct Node{
    int key,siz;
    int a,sum,ans,la,ra;
    int ls,rs;
    int ex,cov,swp;
}tr[N],id;
int n,m,cnt,a[N],rt,r1,r2;
queue<int> q;

inline int rd() {
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline void get(int &x,int &y,pii p) { x = p.first, y = p.second; }
inline void ut(int &x,int y) { x = max(x,y); }


int update(int t) {
    O.siz = L.siz + R.siz + 1;
    O.sum = L.sum + R.sum + O.a;

    O.la = -INF;
    ut(O.la, L.la);
    ut(O.la, L.sum + O.a);
    ut(O.la, L.sum + O.a + R.la);

    O.ra = -INF;
    ut(O.ra, R.ra);
    ut(O.ra, R.sum + O.a);
    ut(O.ra, R.sum + O.a + L.ra);

    O.ans = max(L.ans, R.ans);
    ut(O.ans, L.ra + O.a + R.la);

    return t;
}

int new_Node(int x) {
    int np = 0;
    if (!q.empty()) np = q.front(), q.pop(); else np = ++cnt;
    tr[np].a = x;
    tr[np].key = rand();
    update(np);
    return np;
}

void color(int t,int ex, int cov,int swp) {
    if (ex) {
        O.a = cov;
        O.ans = O.sum = O.siz * cov;
        O.la = O.ra = max(0, O.sum);
        O.ex = 1;
        O.cov = cov; O.swp = 0;
    }
    if (swp) {
        swap(O.la, O.ra);
        swap(O.ls, O.rs);
        O.swp ^= 1;
    }
}

void push_down(int t) {
    if (!O.ex && !O.swp) return ;
    if (O.ls) color(O.ls, O.ex, O.cov, O.swp);
    if (O.rs) color(O.rs, O.ex, O.cov, O.swp);
    O.ex = O.cov = O.swp = 0;
}

int mer(int x,int y) {
    if (!x || !y) return x+y;
    push_down(x);
    push_down(y);
    return tr[x].key < tr[y].key ? 
        ( tr[x].rs = mer( tr[x].rs, y ), update(x) ):
        ( tr[y].ls = mer( x, tr[y].ls ), update(y) );
}

pii spl(int t,int k) {
    if (!k) return MP(0,t);
    if (k == O.siz) return MP(t,0);
    push_down(t);
    int cur = L.siz+1, tmp = 0;
    return k >= cur ? 
        ( get( O.rs, tmp, spl(O.rs, k-cur) ) , update(t), MP(t,tmp) ):
        ( get( tmp, O.ls, spl(O.ls, k) ) , update(t), MP(tmp,t) );
}

void solve1() {
    int pos = rd(), tot = rd();
    n += tot;
    get(r1, r2, spl(rt,pos));
    int nr = 0; 
    for (int _=1;_<=tot;_++) {
        int x = rd();
        int p = new_Node(x);
        nr = mer(nr,p);
    }
    r1 = mer(r1,nr);
    rt = mer(r1,r2);
}

void dfs(int u) {
    if (!u) return ;
    q.push(u);
    dfs(tr[u].ls); dfs(tr[u].rs);
    tr[u] = id;
}

void solve2() {
    int pos = rd(), tot = rd();
    n -= tot;
    get(rt, r2, spl(rt,pos-1));
    get(r1, r2, spl(r2,tot));
    dfs(r1);
    rt = mer(rt, r2);
} 

void fun(int l,int r) {
    get(r1, rt, spl(rt,l-1) );
    get(rt, r2, spl(rt,r-l+1) );
}

void refun() {
    r1 = mer(r1,rt);
    rt = mer(r1,r2);
}

void solve3() {
    int l = rd(), r = l+rd()-1, c = rd();
    fun(l,r);
    color(rt,1,c,0);
    refun();
}

void solve4() {
    int l = rd(), r = l+rd()-1;
    fun(l,r);
    color(rt,0,0,1);
    refun();
}

void solve5() {
    int l = rd(), r = l+rd()-1;
    fun(l,r);
    printf("%d\n",tr[rt].sum);
    refun();
}

void solve6() {
    int l = 1, r = n;
    fun(l,r);
    printf("%d\n",tr[rt].ans);
    refun();
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("sequence.in","r",stdin);
        freopen("sequence.out","w",stdout);
    #endif
    tr[0].ans = -INF;
    n = rd(), m = rd();
    for (int _=1;_<=n;_++) {
        a[_] = rd();
        int p = new_Node(a[_]);
        if (_==1) rt=p; else rt = mer(rt,p);
    }
    while (m--) {
        char cmd[20]; scanf("%s",cmd+1);
        if (cmd[1] == 'I') solve1();
        if (cmd[1] == 'D') solve2();
        if (cmd[1] == 'M' && cmd[3] == 'K') solve3();
        if (cmd[1] == 'R') solve4();
        if (cmd[1] == 'G') solve5();
        if (cmd[1] == 'M' && cmd[3] == 'X') solve6();
    }
    return 0;
}

你可能感兴趣的:([BZOJ1500]维修数列 Treap)