现在的位置: 首页 > 综合 > 正文

浙大2014 3月月赛I题(伸展树)

2014年07月18日 ⁄ 综合 ⁄ 共 3348字 ⁄ 字号 评论关闭

模板:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define ll long long
using namespace std ;

const int maxn = 500011 ;

ll gcd ( ll a , ll b ) {
    return ( b == 0 ? a : gcd ( b , a % b ) ) ;
}

int num[maxn] , f[maxn] , n ;
struct Splay {
	int son[2][maxn] , fa[maxn] , size[maxn] ;
	ll val[maxn] , g[2][maxn] ;
    int statu[maxn] ;
	int tot ;

	void push_up ( int x ) {
		size[x] = 1 ;
		int ls = son[0][x] , rs = son[1][x] ;
		if ( son[0][x] ) size[x] += size[son[0][x]] ;
		if ( son[1][x] ) size[x] += size[son[1][x]] ;
        g[statu[x]][x] = val[x] ;
        g[statu[x]^1][x] = -1 ;
		if ( ls ) {
            if ( g[0][x] == -1 ) {
                g[0][x] = g[0][ls] ;
                if ( g[1][x] == -1 ) g[1][x] = g[1][ls] ;
                else if ( g[1][ls] != -1 ) g[1][x] = gcd ( g[1][x] , g[1][ls] ) ;
            }
            else {
                g[1][x] = g[1][ls] ;
                if ( g[0][ls] != -1 ) g[0][x] = gcd ( g[0][x] , g[0][ls]  ) ;
            }
			if ( rs ) {
                if ( g[0][x] == -1 ) {
                    g[0][x] = g[0][rs] ;
                    if ( g[1][x] == -1 ) g[1][x] = g[1][rs] ;
                    else if ( g[1][rs] != -1 ) g[1][x] = gcd ( g[1][x] , g[1][rs] ) ;
                }
                else {
                    if ( g[1][x] == -1 ) g[1][x] = g[1][rs] ;
                    else if ( g[1][rs] != -1 ) g[1][x] = gcd ( g[1][x] , g[1][rs] ) ;
                    if ( g[0][rs] != -1 ) g[0][x] = gcd ( g[0][x] , g[0][rs] ) ;
                }
            }
		}
		else {
			if ( rs ) {
                if ( g[0][x] == -1 ) {
                    g[0][x] = g[0][rs] ;
                    if ( g[1][x] == -1 ) g[1][x] = g[1][rs] ;
                    else if ( g[1][rs] != -1 ) g[1][x] = gcd ( g[1][x] , g[1][rs] ) ;
                }
                else {
                    g[1][x] = g[1][rs] ;
                    if ( g[0][rs] != -1 ) g[0][x] = gcd ( g[0][x] , g[0][rs] ) ;
                }
            }
		}
	}

	void rot ( int x , int c ) {
		int y = fa[x] , z = fa[y] ;
		son[!c][y] = son[c][x] ;
		if ( son[c][x] ) fa[son[c][x]] = y ;
		fa[x] = z ;
		if ( z ) {
			if ( y == son[0][z] ) son[0][z] = x ;
			else son[1][z] = x ;
		}
		son[c][x] = y , fa[y] = 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 new_node ( int v , int f ) {
		size[++tot] = 1 ;
		val[tot] = v ;
        statu[tot] = f ;
		son[0][tot] = son[1][tot] = fa[tot] = 0 ;
		return tot ;
	}

	int find ( int v , int rt ) {
		int cnt = 0 ;
		if ( son[0][rt] ) cnt += size[son[0][rt]] ;
		if ( cnt + 1 == v ) return rt ;
		if ( cnt >= v ) return find ( v , son[0][rt] ) ;
		return find ( v - cnt - 1 , son[1][rt] ) ;
	}

    int build ( int l , int r ) {
        if ( l > r ) return 0 ;
        int mid = l + r >> 1 ;
        int temp = new_node ( num[mid] , f[mid] ) ;
        son[0][temp] = build ( l , mid - 1 ) ;
        if ( son[0][temp] ) fa[son[0][temp]] = temp ;
        son[1][temp] = build ( mid + 1 , r ) ;
        if ( son[1][temp] ) fa[son[1][temp]] = temp ;
        push_up ( temp ) ;
        return temp ;
    }

    int query ( int l , int r , int st , int rt ) {
        l ++ , r ++ ;
        int temp = find ( l - 1 , rt ) ;
        splay ( temp , 0 ) ;
        rt = temp ;
        temp = find ( r + 1 , rt ) ;
        splay ( temp , rt ) ;
        temp = son[0][temp] ;
        printf ( "%lld\n" , g[st][temp] ) ;
        return rt ;
    }

    int insert ( int pos , ll v , int st , int rt ) {
        pos ++ ;
        int temp = find ( pos , rt ) ;
        splay ( temp , 0 ) ;
        rt = temp ;
        temp = find ( pos + 1 , rt ) ;
        splay ( temp , rt ) ;
        int fuck = new_node ( v , st ) ;
        son[0][temp] = fuck ;
        fa[fuck] = temp ;
        push_up ( fuck ) ;
        push_up ( temp ) ;
        push_up ( rt ) ;
        return rt ;
    }

    int del ( int pos , int rt ) {
        pos ++ ;
        int temp = find ( pos - 1 , rt ) ;
        splay ( temp , 0 ) ;
        rt = temp ;
        temp = find ( pos + 1 , rt ) ;
        splay ( temp , rt ) ;
        son[0][temp] = 0 ;
        push_up ( temp ) ;
        push_up ( rt ) ;
        return rt ;
    }

    int rev ( int pos , int rt ) {
        pos ++ ;
        int temp = find ( pos , rt ) ;
        splay ( temp , 0 ) ;
        rt = temp ;
        statu[rt] ^= 1 ;
        push_up ( rt ) ;
        return rt ;
    }

    int modify ( int pos , int v , int rt ) {
        pos ++ ;
        int temp = find ( pos , rt ) ;
        splay ( temp , 0 ) ;
        rt = temp ;
        val[rt] = v ;
        push_up ( rt ) ;
        return rt ;
    }

} tree ;

int main () {
    int q , a , b ;
    char op[111] ;
    while ( scanf ( "%d%d" , &n , &q )!= EOF ) {
        tree.tot = 0 ;
        int i , j , k ;
        num[0] = num[n+1] = -1 ;
        for ( i = 1 ; i <= n ; i ++ ) scanf ( "%d%d" , &num[i] , &f[i] ) ;
        int rt = tree.build ( 0 , n + 1 ) ;
   //     tree.print ( rt ) ;
        while ( q -- ) {
            scanf ( "%s" , op ) ;
            if ( op[0] == 'Q' ) {
                int l , r , x ;
                scanf ( "%d%d%d" , &l , &r , &x ) ;
                rt = tree.query ( l , r , x , rt ) ;
            }
            else if ( op[0] == 'I' ) {
                scanf ( "%d%d%d" , &i , &j , &k ) ;
                rt = tree.insert ( i , j , k , rt ) ;
            }
            else if ( op[0] == 'D' ) {
                scanf ( "%d" , &i ) ;
                rt = tree.del  ( i , rt ) ;
            }
            else if ( op[0] == 'R' ) {
                scanf ( "%d" , &i ) ;
                rt = tree.rev ( i , rt ) ;
            }
            else {
                scanf ( "%d%d" , &i , &j ) ;
                rt = tree.modify ( i , j , rt ) ;
            }
      //      tree.print ( rt ) ;
     //       puts ( "" ) ;
        }
    }
}
【上篇】
【下篇】

抱歉!评论已关闭.