hdu 4453 Looploop (伸展树)
题意:给出一个数列,然后又五个操作,维护这个数列.。
解题思路:splay tree 。其实这题就是考你伸展树的基本功了。唯一有点思维的地方,就是move的时候,对于两种move,第一种,把指针逆时针移一位,其实就是把最后一个元素插到最前面,在把最后那个删掉。。。第二种反之。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std ; const int maxn = 555555 ; int col[maxn] , num[maxn] , val[maxn] , add[maxn] ; int size[maxn] , son[2][maxn] , fa[maxn] , tot ; int k1 , k2 ; void rev ( int rt ) { if ( !rt ) return ; int ls = son[0][rt] , rs = son[1][rt] ; son[1][rt] = ls ; son[0][rt] = rs ; col[rt] ^= 1 ; } void push_up ( int rt ) { size[rt] = 1 ; if ( son[0][rt] ) size[rt] += size[son[0][rt]] ; if ( son[1][rt] ) size[rt] += size[son[1][rt]] ; } void push_down ( int rt ) { int ls = son[0][rt] , rs = son[1][rt] ; if ( add[rt] ) { if ( ls ) add[ls] += add[rt] , val[ls] += add[rt] ; if ( rs ) add[rs] += add[rt] , val[rs] += add[rt] ; add[rt] = 0 ; } if ( col[rt] ) { rev ( ls ) ; rev ( rs ) ; col[rt] = 0 ; } } int new_node ( ) { size[++tot] = 1 ; son[0][tot] = son[1][tot] = 0 , fa[tot] = 0 ; col[tot] = add[tot] = 0 ; return tot ; } int build ( int l , int r ) { if ( l > r ) return 0 ; int mid = l + r >> 1 ; int temp = new_node () ; val[temp] = num[mid] ; son[0][temp] = build ( l , mid - 1 ) ; son[1][temp] = build ( mid + 1 , r ) ; if ( son[0][temp] ) fa[son[0][temp]] = temp , size[temp] += size[son[0][temp]] ; if ( son[1][temp] ) fa[son[1][temp]] = temp , size[temp] += size[son[1][temp]] ; return temp ; } void rot ( int rt , int c ) { int y = fa[rt] , z = fa[y] ; push_down ( y ) , push_down ( rt ) ; son[!c][y] = son[c][rt] ; if ( son[c][rt] ) fa[son[c][rt]] = y ; fa[rt] = z ; if ( z ) { if ( y == son[0][z] ) son[0][z] = rt ; else son[1][z] = rt ; } son[c][rt] = y , fa[y] = rt ; push_up ( y ) ; } void splay ( int x , int to ) { push_down ( x ) ; 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 rt , int key ) { push_down ( rt) ; int cnt = 0 ; if ( son[0][rt] ) cnt = size[son[0][rt]] ; if ( cnt + 1 == key ) return rt ; if ( cnt + 1 > key ) return find ( son[0][rt] , key ) ; return find ( son[1][rt] , key - cnt - 1 ) ; } int insert ( int l , int x , int rt ) { int temp = find ( rt , l ) ; splay ( temp , 0 ) ; rt = temp ; temp = find ( rt , l + 1 ) ; splay ( temp , rt ) ; int t = new_node () ; val[t] = x ; son[0][temp] = t , fa[t] = temp ; push_up ( temp ) ; push_up ( rt ) ; return rt ; } int del ( int l , int r , int rt ) { int temp = find ( rt , l - 1 ) ; splay ( temp , 0 ) ; rt = temp ; temp = find ( rt , r + 1 ) ; splay ( temp , rt ) ; son[0][temp] = 0 ; push_up ( temp ) ; push_up ( rt ) ; return rt ; } void print ( int rt ) { push_down ( rt ) ; if ( son[0][rt] ) print ( son[0][rt] ) ; printf ( "%d " , val[rt] ) ; if ( son[1][rt] ) print ( son[1][rt] ) ; } int main () { int n , m , i , j , k , x , ca = 0 ; char s[111] ; while ( scanf ( "%d%d%d%d" , &n , &m , &k1 , &k2 ) != EOF ) { if ( n == 0 ) break ; for ( i = 1 ; i <= n ; i ++ ) scanf ( "%d" , &num[i] ) ; printf ( "Case #%d:\n" , ++ ca ) ; tot = 0 ; int rt = build ( 0 , n + 1 ) ; while ( m -- ) { scanf ( "%s" , s ) ; if ( s[0] == 'q' ) { int temp = find ( rt , 2 ) ; splay ( temp , 0 ) ; rt = temp ; printf ( "%d\n" , val[rt] ) ; } else if ( s[0] == 'r' ) { int temp = find ( rt , 1 ) ; splay ( temp , 0 ) ; rt = temp ; temp = find ( rt , 2 + k1 ) ; splay ( temp , rt ) ; rev ( son[0][temp] ) ; } else if ( s[0] == 'i' ) { scanf ( "%d" , &x ) ; rt = insert ( 2 , x , rt ) ; } else if ( s[0] == 'd' ) { rt = del ( 2 , 2 , rt ) ; } else if ( s[0] == 'a' ) { scanf ( "%d" , &x ) ; int temp = find ( rt , 1 ) ; splay ( temp , 0 ) ; rt = temp ; temp = find ( rt , k2 + 2 ) ; splay ( temp , rt ) ; int fuck = son[0][temp] ; val[fuck] += x ; add[fuck] += x ; push_up ( temp ) ; push_up ( rt ) ; } else { scanf ( "%d" , &x ) ; if ( x == 2 ) { int temp = find ( rt , 2 ) ; temp = val[temp] ; rt = del ( 2 , 2 , rt ) ; int len = size[rt] ; rt = insert ( len - 1 , temp , rt ) ; } else { int len = size[rt] ; int temp = find ( rt , len - 1 ) ; temp = val[temp] ; rt = del ( len - 1 , len - 1 , rt ) ; rt = insert ( 1 , temp , rt ) ; } } } } return 0 ; }