[NOI2005]维修数列

[NOI2005]维修数列

中文题,题意不解释。。
平衡树模板,做法不解释。。就看你模板是否够硬了。。
无论在哪种数据结构中,我对push_down( int rt )的理解是,rt节点的信息已经是真实的,而其子节点并不一定真实,因为当前节点上可能还有延迟标记,因而,其作用是将当前节点的延迟信息推送到子节点上,使其子节点真实。
先来发伸展树:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std ;
 
const int maxn = 1000502 ;
const int INF = 1111111111 ;
 
int size[maxn] , fa[maxn] , son[2][maxn] ;
int sum[maxn] , col[maxn] , val[maxn] , re[maxn] ;
int mm[maxn] , rm[maxn] , lm[maxn] , num[maxn] ;
int sta[maxn] , top ;
int tot , n ;
 
int fun()
{
       char ch;
       int flag=1,a=0;
       while(ch=getchar())
       {
              if((ch>='0'&&ch<='9')||ch=='-')break;
       }
       if(ch=='-')flag=-1;
       else a=ch-'0';
       while(ch=getchar())
       {
              if(ch>='0'&&ch<='9')a=10*a+ch-'0';
              else break;
       }
       return flag*a;
}
 
int max ( int a , int b ) { return a > b ? a : b ; }
 
void push_up(int x){
    int l=son[0][x],r=son[1][x];
    size[x]=size[l]+size[r]+1;
    sum[x]=sum[l]+sum[r]+val[x];
    lm[x]=max(lm[l],sum[l]+val[x]+max(0,lm[r]));
    rm[x]=max(rm[r],sum[r]+val[x]+max(0,rm[l]));
    mm[x]=max(0,rm[l])+val[x]+max(0,lm[r]);
    mm[x]=max(mm[l],max(mm[r],mm[x]));
}
void up_rev ( int rt ) {
    if ( !rt ) return ;
    swap ( son[0][rt] , son[1][rt] ) ;
    swap ( lm[rt] , rm[rt] ) ;
    col[rt] ^= 1 ;
}
 
void up_mak ( int rt , int v ) {
    if ( !rt ) return ;
    re[rt] = val[rt] = v ;
    sum[rt] = val[rt] * size[rt] ;
    mm[rt] = lm[rt] = rm[rt] = ( val[rt] > 0 ? sum[rt] : val[rt] ) ;
}
 
void push_down ( int rt ) {
    int ls = son[0][rt] , rs = son[1][rt] ;
    if ( col[rt] ) {
        up_rev ( ls ) ;
        up_rev ( rs ) ;
        col[rt] = 0 ;
    }
    if ( re[rt] != INF ) {
        up_mak ( ls , re[rt] ) ;
        up_mak ( rs , re[rt] ) ;
        re[rt] = INF ;
    }
}
 
void down ( int x ) {
    if ( !x ) return ;
    down ( fa[x] ) ;
    push_down ( x ) ;
}
 
void rot ( int x , int c ) {
    int y = fa[x] , z = fa[y] ;
    push_down ( y ) , push_down ( x ) ;
    son[!c][y] = son[c][x] ;
    if ( son[c][x] ) fa[son[c][x]] = y ;
    son[c][x] = y , fa[y] = x ;
    fa[x] = z ;
    if ( z ) {
        if ( y == son[0][z] ) son[0][z] = x ;
        else son[1][z] = x ;
    }
    push_up ( y ) ;
}
 
void splay ( int x , int to ) {
    while ( fa[x] != to ) {
        if ( fa[fa[x]] == to ) rot ( x , x == son[0][fa[x]] ) ;
        else {
            int y = fa[x] , z = fa[y] ;
            if ( x == son[0][y] ) {
                if ( y == son[0][z] ) rot ( y , 1 ) , rot ( x , 1 ) ;
                else rot ( x , 1 ) , rot ( x , 0 ) ;
            }
            else {
                if ( y == son[1][z] ) rot ( y , 0 ) , rot ( x , 0 ) ;
                else rot ( x , 0 ) , rot ( x , 1 ) ;
            }
        }
    }
    push_up ( x ) ;
}
 
int find ( int k , int rt ) {
    push_down ( rt ) ;
    int cnt = 0 ;
    if ( son[0][rt] ) cnt += size[son[0][rt]] ;
    if ( cnt + 1 == k ) return rt ;
    if ( cnt >= k ) return find ( k , son[0][rt] ) ;
    return find ( k - cnt - 1 , son[1][rt] ) ;
}
 
void init ( int p ) {
    size[p] = 1 ;
    son[0][p] = son[1][p] = fa[p] = 0 ;
    mm[p] = lm[p] = rm[p] = -INF ;
    val[p] = -INF , re[p] = INF , col[p] = 0 ;
}
 
int new_node () {
    tot ++ ;
    init ( tot ) ;
    return tot ;
}
 
int build ( int l , int r ) {
    if ( l > r ) return 0 ;
    int m = ( l + r ) >> 1 ;
    int p = new_node () ;
    if ( m != 0 && m != n + 1 ) val[p] = num[m] ;
    son[0][p] = build ( l , m - 1 ) ;
    if ( son[0][p] ) fa[son[0][p]] = p ;
    son[1][p] = build ( m + 1 , r ) ;
    if ( son[1][p] ) fa[son[1][p]] = p ;
    push_up ( p ) ;
    return p ;
}
 
void reuse ( int  rt ) {
    sta[++top] = rt ;
    if ( son[0][rt] ) reuse ( son[0][rt] ) ;
    if ( son[1][rt] ) reuse ( son[1][rt] ) ;
    init ( rt ) ;
}
 
int add[maxn] ;
 
int insert ( int rt ) {
    int pos , t , i , last ;
    pos = fun () ; t = fun() ;
    if ( t <= 0 ) return rt ;
    pos ++ ;
    int temp = find ( pos , rt ) ;
    splay ( temp , 0 ) ;
    rt = temp ;
    temp = find ( pos + 1 , rt ) ;
    splay ( temp , rt ) ;
    for ( i = 1 ; i <= t ; i ++ ) {
        add[i] = ( top ? sta[top--] : new_node () ) ;
        val[add[i]] = fun () ;
    }
    son[1][add[t]] = temp , fa[temp] = add[t] ;
    push_up ( add[t] ) ;
    for ( i = t - 1 ; i >= 1 ; i -- ) {
        son[1][add[i]] = add[i+1] ;
        fa[add[i+1]] = add[i] ;
        push_up ( add[i] ) ;
    }
    son[1][rt] = add[1] , fa[add[1]] = rt ;
    push_up ( rt ) ;
    return rt ;
}
 
int del ( int rt ) {
    int pos , t ;
    pos = fun () ; t = fun () ;
    if ( t <= 0 ) return rt ;
    pos ++ ;
    int temp = find ( pos - 1 , rt ) ;
    splay ( temp , 0 ) ;
    rt = temp ;
    temp = find ( pos + t , rt ) ;
    splay ( temp , rt ) ;
    reuse ( son[0][temp] ) ;
    son[0][temp] = 0 ;
    push_up ( temp ) ;
    push_up ( rt ) ;
    return rt ;
}
 
int make ( int rt ) {
    int pos , t , fix ;
    pos = fun () ; t = fun () ; fix = fun () ;
    if ( t <= 0 ) return rt ;
    pos ++ ;
    int temp = find ( pos - 1 , rt ) ;
    splay ( temp , 0 ) ;
    rt = temp ;
    temp = find ( pos + t , rt ) ;
    splay ( temp , rt ) ;
    int x = son[0][temp] ;
    up_mak ( x , fix ) ;
    push_up ( temp ) ;
    push_up ( rt ) ;
    return rt ;
}
 
int rev ( int rt ) {
    int pos , t ;
    pos = fun () ; t = fun () ;
    if ( t <= 1 ) return rt ;
    pos ++ ;
    int temp = find ( pos - 1 , rt ) ;
    splay ( temp , 0 ) ;
    rt = temp ;
    temp = find ( pos + t , rt ) ;
    splay ( temp , rt ) ;
    int x = son[0][temp] ;
    up_rev ( x ) ;
    push_up ( temp ) ;
    push_up ( rt ) ;
    return rt ;
}
 
int get ( int rt ) {
    int pos , t ;
    pos = fun () ; t = fun () ;
    if ( t <= 0 ) {
        puts ( "0" ) ;
        return rt ;
    }
    pos ++ ;
    int temp = find ( pos - 1 , rt ) ;
    splay ( temp , 0 ) ;
    rt = temp ;
    temp = find ( pos + t , rt ) ;
    splay ( temp , rt ) ;
    printf ( "%d\n" , sum[son[0][temp]] ) ;
    return rt ;
}
 
int max_sum ( int rt ) {
    printf ( "%d\n" , mm[rt] ) ;
    return rt ;
}
 
char op[111] ;
int main () {
    int m , i ;
//  freopen ( "sequence8.in" , "r" , stdin ) ;
 // freopen ( "ans1.txt" , "w" , stdout ) ;
    while ( scanf ( "%d%d" , &n , &m ) != EOF ) {
        tot = top = 0 ;
        init ( 0 ) ;
        size[0] = sum[0] = 0 ;
        for ( i = 1 ; i <= n ; i ++ ) {
            num[i] = fun () ;
        }
        int root = build ( 0 , n + 1 ) ;
        while ( m -- ) {
            scanf ( "%s"  , op ) ;
            if ( op[2] == 'S' ) root = insert ( root ) ;
            else if ( op[2] == 'L' ) root = del ( root ) ;
            else if ( op[2] == 'K' ) root = make ( root ) ;
            else if ( op[2] == 'V' ) root = rev ( root ) ;
            else if ( op[2] == 'T' ) root = get ( root ) ;
            else root = max_sum ( root ) ;
        }
    }
}


再来一发treap
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <map>
#include <math.h>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <stdlib.h>
#include <time.h>
#define ll int
using namespace std;
 
const int INF = 1111111111 ;
int fun()
{
    char ch;
    int flag=1,a=0;
    while(ch=getchar())
    {
        if((ch>='0'&&ch<='9')||ch=='-')break;
    }
    if(ch=='-')flag=-1;
    else a=ch-'0';
    while(ch=getchar())
    {
        if(ch>='0'&&ch<='9')a=10*a+ch-'0';
        else break;
    }
    return flag*a;
}
 
const int maxn = 1020001 ;
int num[maxn] ;
 
struct Treap {
    int c[2][maxn] , size[maxn] , tot ;
    ll sum[maxn] , val[maxn] , col[maxn] , mx[maxn] , lm[maxn] , rm[maxn] ;
    int f[maxn] , sta[maxn] , top , p[maxn] ;
 
    void init () {
        tot = top = 0 ;
        mx[0] = lm[0] = rm[0] = - INF ;
    }
 
    void push_up ( int x ) {
        int l=c[0][x],r=c[1][x];
        size[x]=size[l]+size[r]+1;
        sum[x]=sum[l]+sum[r]+val[x];
        lm[x]=max(lm[l],sum[l]+val[x]+max(0,lm[r]));
        rm[x]=max(rm[r],sum[r]+val[x]+max(0,rm[l]));
        mx[x]=max(0,rm[l])+val[x]+max(0,lm[r]);
        mx[x]=max(mx[l],max(mx[r],mx[x]));
    }
 
    void rev ( int rt ) {
        if ( !rt ) return ;
        f[rt] ^= 1 ;
        swap ( lm[rt] , rm[rt] ) ;
        swap ( c[0][rt] , c[1][rt] ) ;
    }
 
    void color ( int rt , int v ) {
        if ( !rt ) return ;
        mx[rt] = val[rt] = col[rt] = v ;
        sum[rt] = size[rt] * v ;
        if ( v > 0 ) mx[rt] = lm[rt] = rm[rt] = size[rt] * v ;
        else lm[rt] = rm[rt] = 0 ;
    }
 
    void push_down ( int rt ) {
        int ls = c[0][rt] , rs = c[1][rt] ;
        if ( f[rt] ) {
            rev ( ls ) ;
            rev ( rs ) ;
            f[rt] = 0 ;
        }
        if ( col[rt] != INF ) {
            color ( ls , col[rt] ) ;
            color ( rs , col[rt] ) ;
            col[rt] = INF ;
        }
    }
 
    int ran ( int rt ) {
        static int rans = 123456789 ;
        return rans += rans << 2 | 1 ;
    }
    int new_node ( ll v ) {
        int temp ;
        if ( top ) temp = sta[top--] ;
        else temp = ++ tot ;
        p[temp] = ran ( temp ) ;
        size[temp] = 1 ;
        val[temp] = sum[temp] = mx[temp] = v ;
        c[0][temp] = c[1][temp] = f[temp] = 0 ;
        col[temp] = INF ;
        lm[temp] = rm[temp] = max ( (ll) 0 , v ) ;
        return temp ;
    }
 
    int merge ( int x , int y ) {
        if ( !x ) return y ;
        if ( !y ) return x ;
        push_down ( x ) ; push_down ( y ) ;
        if ( p[x] < p[y] ) {
            c[1][x] = merge ( c[1][x] , y ) ;
            push_up ( x ) ;
            return x ;
        }
        c[0][y] = merge ( x , c[0][y] ) ;
        push_up ( y ) ;
        return y ;
    }
 
    void split ( int rt , int &x , int &y , int k ) {
        if ( k == 0 ) { x = 0 , y = rt ; return ; }
        push_down ( rt ) ;
        int ls = c[0][rt] , rs = c[1][rt] ;
        if ( size[ls] + 1 == k ) {
            x = rt , y = c[1][rt] ;
            c[1][rt] = 0 ;
            push_up ( rt ) ;
            return ;
        }
        if ( size[ls] + 1 < k ) {
            split ( c[1][rt] , x , y , k - size[ls] - 1 ) ;
            c[1][rt] = x ; x = rt ;
            push_up ( rt ) ;
            return ;
        }
        split ( c[0][rt] , x , y , k ) ;
        c[0][rt] = y ; y = rt ;
        push_up ( rt ) ;
    }
 
    int Insert ( int rt , int l , int v ) {
        if ( v <= 0 ) return rt ;
        int x , y , temp = 0 ;
        temp = build ( 1 , v ) ;
        if ( !rt ) return temp ;
        split ( rt , x , y , l ) ;
        temp = merge ( x , temp ) ; temp = merge ( temp , y ) ;
        return temp ;
    }
 
    void del ( int rt ) {
        if ( !rt ) return ;
        sta[++top] = rt ;
        del ( c[0][rt] ) ;
        del ( c[1][rt] ) ;
    }
 
    int Del ( int rt , int l , int k ) {
        int x , y , temp = 0 ;
        split ( rt , x , temp , l - 1 ) ;
        split ( temp , temp , y , k ) ;
        del ( temp ) ;
        rt = merge ( x , y ) ;
        return rt ;
    }
 
    int Mk_sm ( int rt , int l , int k , int v ) {
        int x , y , temp = 0 ;
        split ( rt , x , temp , l - 1 ) ;
        split ( temp , temp , y , k ) ;
        color ( temp , v ) ;
        temp = merge ( x , temp ) ; temp = merge ( temp , y ) ;
        return temp ;
    }
 
    int Reverse ( int rt , int l , int k ) {
        int x , y , temp ;
        split ( rt , x , temp , l - 1 ) ;
        split ( temp , temp , y , k ) ;
        rev ( temp ) ;
        temp = merge ( x , temp ) ; temp = merge ( temp , y ) ;
        return temp ;
    }
 
    ll Get_sum ( int &rt , int l , int k ) {
        int x , y , temp ;
        split ( rt , x , temp , l - 1 ) ;
        split ( temp , temp , y , k ) ;
        ll ans = sum[temp] ;
        temp = merge ( x , temp ) ; temp = merge ( temp , y ) ;
        rt = temp ;
        return ans ;
    }
 
    ll Max_sum ( int rt ) {
        return mx[rt] ;
    }
 
    int build ( int l , int r ) {
        if ( l > r ) return 0 ;
        int mid = l + r >> 1 ;
        int temp = new_node ( num[mid] ) ;
        c[0][temp] = build ( l , mid - 1 ) ;
        c[1][temp] = build ( mid + 1 , r ) ;
        push_up ( temp ) ;
        return temp ;
    }
    void print ( int rt ) {
        if ( !rt ) return ;
        print ( c[0][rt] ) ;
        printf ( "%d " , val[rt] ) ;
        print ( c[1][rt] ) ;
    }
} tree ;
 
int main() {
    int n , m , i , j , k , l , c ;
    while ( scanf ( "%d%d" , &n , &m ) != EOF ) {
        tree.init () ;
        int rt = 0 ;
        for ( i = 1 ; i <= n ; i ++ )
            num[i] = fun () ;
        rt = tree.build ( 1 , n ) ;
        char op[1111] ;
        while ( m -- ) {
            scanf ( "%s" , op ) ;
            if ( op[0] == 'I' ) {
                j = fun () ; k = fun () ;
                for ( i = 1 ; i <= k ; i ++ ) {
                    num[i] = fun () ;
                }
                rt = tree.Insert ( rt ,j , k ) ;
            }
            else if ( op[0] == 'D' ) {
                j = fun () ; k = fun () ;
                if ( k < 0 ) continue ;
                rt = tree.Del ( rt , j , k ) ;
            }
            else if ( op[0] == 'M' && op[1] == 'A' && op[2] == 'K' ) {
                j = fun () ; k = fun () ; c = fun () ;
                if ( k <= 0 ) continue ;
                rt = tree.Mk_sm ( rt , j , k , c ) ;
            }
            else if ( op[0] == 'G' ) {
                j = fun () ; k = fun () ;
                if ( k <= 0 ) {
                    puts ( "0" ) ;
                    continue ;
                }
                printf ( "%d\n" , tree.Get_sum ( rt , j , k ) ) ;
            }
            else if ( op[0] == 'R' ) {
                j = fun () ; k = fun () ;
                if ( k <= 1 ) continue ;
                rt = tree.Reverse ( rt , j , k ) ;
            }
            else {
                printf ( "%d\n" , tree.Max_sum ( rt ) ) ;
            }
        }
    }
    return 0;
}


你可能感兴趣的:(平衡树)