[序列终结者]( Splay树 )

From:http://www.lydsy.com/JudgeOnline/problem.php?id=1251

Solution: 维护数列的简单版

/**************************************************************
    Problem: 1251
    User: leezy
    Language: C++
    Result: Accepted
    Time:9312 ms
    Memory:2840 kb
****************************************************************/
 
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cmath>
using namespace std;
#define N 50015
#define M 1000000
#define INF (1<<29)
struct SPLAY { int v,l,r,p,s,delta,rev,Max;} t[N];
int cnt,root;
#define KT t[root].r
void Dump(int x){
    if ( x ){
        printf("%d[v=%d,Max=%d,rev=%d,delta=%d][L=%d,R=%d]\n",
            x,t[x].v,t[x].Max,t[x].rev,t[x].delta,t[x].l,t[x].r);
        Dump(t[x].l); Dump(t[x].r);
    }
}
int NewNode(int v, int fa){
    t[++cnt].v = t[cnt].Max = v;
    t[cnt].l = t[cnt].r = 0;
    t[cnt].delta = t[cnt].rev = 0;
    t[cnt].s = 1; t[cnt].p = fa;
    return cnt;
}
void Upd_Down(int x){
    int L = t[x].l, R = t[x].r;
    if ( t[x].delta ){
        t[x].v += t[x].delta;
        t[x].Max = max(t[x].Max+t[x].delta, t[x].v);
        if ( L ) t[L].delta += t[x].delta;
        if ( R ) t[R].delta += t[x].delta;
        t[x].delta = 0;
    }
    if ( t[x].rev ){
        swap(t[x].l, t[x].r);
        if ( L ) t[L].rev ^= 1;
        if ( R ) t[R].rev ^= 1;
        t[x].rev = 0;
    }
}
void Upd_Up(int x){
    if ( x ){
        int L = t[x].l, R = t[x].r;
        if ( L ) Upd_Down(L);
        if ( R ) Upd_Down(R);
        t[x].s = t[L].s + t[R].s + 1;
        t[x].Max = max(t[L].Max, t[x].v);
        t[x].Max = max(t[R].Max, t[x].Max);
    }
}
int Build(int l, int r, int fa)
{
    if ( l <= r ){
        int mid = (l+r)>>1;
        int k = NewNode(0, fa);
        t[k].p = fa;
        t[k].l = Build(l, mid-1, k);
        t[k].r = Build(mid+1, r, k);
        Upd_Up(k);
        return k;
    }
    return 0;
}
void Rot_L(int x){
    int y = t[x].r;
    Upd_Down(y); Upd_Down(x);
    t[x].r = t[y].l; t[t[y].l].p = x;
    t[y].p = t[x].p;
    if ( !t[x].p ) root = y;
    else if ( t[t[x].p].l == x ) t[t[x].p].l = y;
    else t[t[x].p].r = y;
    t[y].l = x; t[x].p = y;
    Upd_Up(x); Upd_Up(y);
}
void Rot_R(int x){
    int y = t[x].l;
    Upd_Down(y); Upd_Down(x);
    t[x].l = t[y].r; t[t[y].r].p = x;
    t[y].p = t[x].p;
    if ( !t[x].p ) root = y;
    else if ( t[t[x].p].l == x ) t[t[x].p].l = y;
    else t[t[x].p].r = y;
    t[y].r = x; t[x].p = y;
    Upd_Up(x); Upd_Up(y);
}
void Splay(int x, int to){
    Upd_Down(x);
    while ( t[x].p != to ){
        int p1 = t[x].p;
        int p2 = t[p1].p;
        if ( t[p1].l == x ){
            if ( p2 == to ) Rot_R(p1);
            else if ( t[p2].l == p1 ) Rot_R(p2), Rot_R(p1);
            else Rot_R(p1), Rot_L(p2);
        } else {
            if ( p2 == to ) Rot_L(p1);
            else if ( t[p2].r == p1 ) Rot_L(p2), Rot_L(p1);
            else Rot_L(p1), Rot_R(p2);
        }
    }
    Upd_Up(x);
    //Dump(root); printf("\n");
}
int Get_Kth(int x, int k){
    Upd_Down(x);
    int kk = t[t[x].l].s + 1;
    if ( kk == k ) return x;
    if ( kk < k ) return Get_Kth(t[x].r, k-kk);
    return Get_Kth(t[x].l, k);
}
void Modify(int l, int r, int v){
    //printf("Modify\n");
    int x = Get_Kth(root, l);
    int y = Get_Kth(root, r+2);
    Splay(x, 0);
    Splay(y, x);
    t[t[KT].l].delta += v;
    Upd_Down(t[KT].l);
    //Dump(root); printf("\n");
}
void Reverse(int l, int r){
    //printf("Reverse\n");
    int x = Get_Kth(root, l);
    int y = Get_Kth(root, r+2);
    Splay(x, 0);
    Splay(y, x);
    t[t[KT].l].rev = 1;
    Upd_Down(t[KT].l);
    //Dump(root); printf("\n");
}
int GetMax(int l, int r){
    //printf("GetMax\n");
    int x = Get_Kth(root, l);
    int y = Get_Kth(root, r+2);
    Splay(x, 0); Splay(y, x);
    //Dump(root); printf("\n");
    return t[t[KT].l].Max;
}
void Init(int n){
    cnt = root = 0;
    t[0].v = t[0].Max = -INF;
    t[0].delta = t[0].rev = 0;
    t[0].s = t[0].l = t[0].r = t[0].p = 0;
    root = NewNode(-INF, 0);
    t[root].r = NewNode(-INF, root);
    Upd_Up( root );
    t[t[root].r].l = Build(0, n-1, t[root].r);
    Upd_Up(t[root].r); Upd_Up(root);
}
int main()
{
    //const char path[] = "D:\\Project\\AlgorithmExam\\test.txt";
    //freopen(path, "r+", stdin);
 
    int n,m;
    while ( scanf("%d%d", &n, &m) != EOF ){
        Init(n);
        int K,L,R,V;
        for ( int i = 0; i < m; ++i ){
            scanf("%d%d%d", &K, &L, &R);
            if ( 1 == K ){
                scanf("%d", &V);
                Modify(L, R, V);
            } else if ( 2 == K ){
                Reverse(L, R);
            } else {
                printf("%d\n", GetMax(L,R));
            }
        }
    }
    return 0;
}

 

posted on 2013-11-25 21:01  leezyli  阅读(165)  评论(0编辑  收藏  举报

导航