替罪羊树
#include <bits/stdc++.h> using namespace std; const double alpha = 0.725 ;
const int N = 2e6 + 10 ; struct Spgtree { int ls[ N] , rs[ N] , val[ N] , num[ N] , fac[ N] , sz[ N] , sum[ N] , cnt, root; int top, stk[ N] ; void update ( int rt) { fac[ rt] = fac[ ls[ rt] ] + fac[ rs[ rt] ] + ( num[ rt] ? 1 : 0 ) ; sz[ rt] = sz[ ls[ rt] ] + sz[ rs[ rt] ] + 1 ; sum[ rt] = sum[ ls[ rt] ] + sum[ rs[ rt] ] + num[ rt] ; } void dfs ( int rt) { if ( ! rt) { return ; } dfs ( ls[ rt] ) ; if ( num[ rt] ) { stk[ ++ top] = rt; } dfs ( rs[ rt] ) ; } int build ( int l, int r) { if ( l > r) { return 0 ; } if ( l == r) { ls[ stk[ l] ] = rs[ stk[ l] ] = 0 ; update ( stk[ l] ) ; return stk[ l] ; } int mid = l + r >> 1 ; ls[ stk[ mid] ] = build ( l, mid - 1 ) , rs[ stk[ mid] ] = build ( mid + 1 , r) ; update ( stk[ mid] ) ; return stk[ mid] ; } void rebuild ( int & rt) { top = 0 ; dfs ( rt) ; rt = build ( 1 , top) ; } bool imbalence ( int rt) { return sum[ rt] && ( alpha * sz[ rt] <= max ( sz[ ls[ rt] ] , sz[ rs[ rt] ] ) || alpha * sz[ rt] >= fac[ rt] ) ; } void insert ( int & rt, int value) { if ( ! rt) { rt = ++ cnt, val[ rt] = value, num[ rt] = 1 ; update ( rt) ; return ; } if ( val[ rt] == value) { num[ rt] ++ ; } else if ( value < val[ rt] ) { insert ( ls[ rt] , value) ; } else { insert ( rs[ rt] , value) ; } update ( rt) ; if ( imbalence ( rt) ) { rebuild ( rt) ; } } void insert ( int value) { insert ( root, value) ; } void erase ( int & rt, int value) { if ( ! rt) { return ; } if ( val[ rt] == value) { num[ rt] -- ; } else if ( value < val[ rt] ) { erase ( ls[ rt] , value) ; } else { erase ( rs[ rt] , value) ; } update ( rt) ; if ( imbalence ( rt) ) { rebuild ( rt) ; } } void erase ( int value) { erase ( root, value) ; } int get_rank ( int value) { int rt = root, rank = 1 ; while ( rt) { if ( value <= val[ rt] ) { rt = ls[ rt] ; } else { rank + = num[ rt] + sum[ ls[ rt] ] ; rt = rs[ rt] ; } } return rank; } int get_num ( int rank) { int rt = root; while ( rt) { if ( num[ rt] && sum[ ls[ rt] ] < rank && sum[ ls[ rt] ] + num[ rt] >= rank) { break ; } if ( sum[ ls[ rt] ] >= rank) { rt = ls[ rt] ; } else { rank - = sum[ ls[ rt] ] + num[ rt] ; rt = rs[ rt] ; } } return val[ rt] ; }
} tree; int main ( ) { return 0 ;
}
fhq treap
维护值
#include <bits/stdc++.h> using namespace std; const int N = 2e6 + 10 ; mt19937 rnd ( 233 ) ; struct fhqtreap { int ls[ N] , rs[ N] , val[ N] , key[ N] , sz[ N] , root, cnt; inline int new_node ( int value) { cnt++ ; val[ cnt] = value, sz[ cnt] = 1 , key[ cnt] = rnd ( ) ; return cnt; } void update ( int rt) { sz[ rt] = sz[ ls[ rt] ] + sz[ rs[ rt] ] + 1 ; } void split ( int rt, int value, int & x, int & y) { if ( ! rt) { x = y = 0 ; return ; } if ( val[ rt] <= value) { x = rt; split ( rs[ rt] , value, rs[ rt] , y) ; } else { y = rt; split ( ls[ rt] , value, x, ls[ rt] ) ; } update ( rt) ; } int merge ( int x, int y) { if ( ! x || ! y) { return x | y; } if ( key[ x] < key[ y] ) { ls[ y] = merge ( x, ls[ y] ) ; update ( y) ; return y; } else { rs[ x] = merge ( rs[ x] , y) ; update ( x) ; return x; } } void insert ( int value) { int x, y; split ( root, value, x, y) ; root = merge ( merge ( x, new_node ( value) ) , y) ; } void erase ( int value) { int x, y, z; split ( root, value, x, z) ; split ( x, value - 1 , x, y) ; y = merge ( ls[ y] , rs[ y] ) ; root = merge ( merge ( x, y) , z) ; } int get_num ( int rank) { int rt = root; while ( rt) { if ( sz[ ls[ rt] ] + 1 == rank) { break ; } else if ( sz[ ls[ rt] ] >= rank) { rt = ls[ rt] ; } else { rank - = sz[ ls[ rt] ] + 1 ; rt = rs[ rt] ; } } return val[ rt] ; } int get_rank ( int value) { int x, y, rank; split ( root, value - 1 , x, y) ; rank = sz[ x] + 1 ; root = merge ( x, y) ; return rank; } int pre ( int value) { int x, y, rt; split ( root, value - 1 , x, y) ; rt = x; while ( rs[ rt] ) { rt = rs[ rt] ; } root = merge ( x, y) ; return val[ rt] ; } int suc ( int value) { int x, y, rt; split ( root, value, x, y) ; rt = y; while ( ls[ rt] ) { rt = ls[ rt] ; } root = merge ( x, y) ; return val[ rt] ; }
} tree; int main ( ) { return 0 ;
}
维护区间
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10 ; mt19937 rnd ( 233 ) ; struct fhqtreap { int ls[ N] , rs[ N] , val[ N] , key[ N] , sz[ N] , rev[ N] , cnt, root; int new_node ( int value) { cnt++ ; val[ cnt] = value, key[ cnt] = rnd ( ) , sz[ cnt] = 1 ; return cnt; } void push_down ( int rt) { if ( rev[ rt] ) { swap ( ls[ rt] , rs[ rt] ) ; rev[ ls[ rt] ] ^ = 1 , rev[ rs[ rt] ] ^ = 1 ; rev[ rt] = 0 ; } } void push_up ( int rt) { sz[ rt] = sz[ ls[ rt] ] + sz[ rs[ rt] ] + 1 ; } void split ( int rt, int siz, int & x, int & y) { if ( ! rt) { x = y = 0 ; return ; } push_down ( rt) ; if ( sz[ ls[ rt] ] < siz) { x = rt; split ( rs[ rt] , siz - sz[ ls[ rt] ] - 1 , rs[ rt] , y) ; } else { y = rt; split ( ls[ rt] , siz, x, ls[ rt] ) ; } push_up ( rt) ; } int merge ( int x, int y) { if ( ! x || ! y) { return x | y; } if ( key[ x] < key[ y] ) { push_down ( x) ; rs[ x] = merge ( rs[ x] , y) ; push_up ( x) ; return x; } else { push_down ( y) ; ls[ y] = merge ( x, ls[ y] ) ; push_up ( y) ; return y; } } void reverse ( int l, int r) { int x, y, z; split ( root, l - 1 , x, y) ; split ( y, r - l + 1 , y, z) ; rev[ y] ^ = 1 ; root = merge ( merge ( x, y) , z) ; } void print ( int rt) { if ( ! rt) { return ; } push_down ( rt) ; print ( ls[ rt] ) ; printf ( "%d " , val[ rt] ) ; print ( rs[ rt] ) ; } void print ( ) { print ( root) ; } void build ( int n) { for ( int i = 1 ; i <= n; i++ ) { root = merge ( root, new_node ( i) ) ; } }
} tree; int main ( ) { int n, m; scanf ( "%d %d" , & n, & m) ; tree. build ( n) ; for ( int i = 1 ; i <= m; i++ ) { int l, r; scanf ( "%d %d" , & l, & r) ; tree. reverse ( l, r) ; } tree. print ( ) , putchar ( '\n' ) ; return 0 ;
}
#include <bits/stdc++.h> using namespace std; const int N = 2e5 + 10 ; string str[ N] ; mt19937 rnd ( 233 ) ; struct Treap { int ls[ N] , rs[ N] , val[ N] , sz[ N] , key[ N] , root, cnt; void push_up ( int rt) { sz[ rt] = sz[ ls[ rt] ] + sz[ rs[ rt] ] + 1 ; } int new_node ( int value) { cnt++ ; val[ cnt] = value, sz[ cnt] = 1 , key[ cnt] = rnd ( ) ; return cnt; } void split ( int rt, int maxn, int & x, int & y) { if ( ! rt) { x = y = 0 ; return ; } if ( sz[ ls[ rt] ] < maxn) { x = rt; split ( rs[ rt] , maxn - sz[ ls[ rt] ] - 1 , rs[ x] , y) ; } else { y = rt; split ( ls[ rt] , maxn, x, ls[ rt] ) ; } push_up ( rt) ; } int merge ( int x, int y) { if ( ! x || ! y) { return x | y; } if ( key[ x] < key[ y] ) { rs[ x] = merge ( rs[ x] , y) ; push_up ( x) ; return x; } else { ls[ y] = merge ( x, ls[ y] ) ; push_up ( y) ; return y; } } void insert ( int pos, int value) { int x, y; split ( root, pos, x, y) ; root = merge ( merge ( x, new_node ( value) ) , y) ; } int get_num ( int rank) { int x, y, z, ans; split ( root, rank, x, y) ; split ( y, 1 , y, z) ; ans = val[ y] ; root = merge ( merge ( x, y) , z) ; return ans; } void build ( int n) { for ( int i = 1 ; i <= n; i++ ) { root = merge ( root, new_node ( i) ) ; } }
} tree; int main ( ) { ios:: sync_with_stdio ( false ) , cin. tie ( 0 ) , cout. tie ( 0 ) ; int n, m, q, cnt = 0 ; cin >> n; for ( int i = 1 ; i <= n; i++ ) { cin >> str[ ++ cnt] ; } tree. build ( cnt) ; cin >> m; for ( int i = 1 , pos; i <= m; i++ ) { cin >> str[ ++ cnt] >> pos; tree. insert ( pos, cnt) ; } cin >> q; for ( int i = 1 , x; i <= q; i++ ) { cin >> x; cout << str[ tree. get_num ( x) ] << "\n" ; } return 0 ;
}
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10 ; mt19937 rnd ( 233 ) ; int minn, maxn; struct Tree { int ls[ N] , rs[ N] , val[ N] , sz[ N] , key[ N] , root, cnt; void push_up ( int rt) { sz[ rt] = sz[ ls[ rt] ] + sz[ rs[ rt] ] + 1 ; } int new_node ( int value, int pos) { val[ value] = pos, sz[ value] = 1 , key[ value] = rnd ( ) ; return value; } void split ( int rt, int value, int & x, int & y) { if ( ! rt) { x = y = 0 ; return ; } if ( val[ rt] <= value) { x = rt; split ( rs[ rt] , value, rs[ rt] , y) ; } else { y = rt; split ( ls[ rt] , value, x, ls[ rt] ) ; } push_up ( rt) ; } int merge ( int x, int y) { if ( ! x || ! y) { return x | y; } if ( key[ x] < key[ y] ) { rs[ x] = merge ( rs[ x] , y) ; push_up ( x) ; return x; } else { ls[ y] = merge ( x, ls[ y] ) ; push_up ( y) ; return y; } } int get_num ( int rt, int rank) { while ( rt) { if ( sz[ ls[ rt] ] + 1 == rank) { break ; } if ( sz[ ls[ rt] ] >= rank) { rt = ls[ rt] ; } else { rank - = sz[ ls[ rt] ] + 1 ; rt = rs[ rt] ; } } return rt; } int get_num ( int rank) { return get_num ( root, rank) ; } void insert ( int value, int pos) { int x, y; split ( root, pos, x, y) ; root = merge ( merge ( x, new_node ( value, pos) ) , y) ; } void update ( int value, int op) { int x, y, z; split ( root, val[ value] , x, z) ; split ( x, val[ value] - 1 , x, y) ; if ( op) { val[ value] = -- minn; root = merge ( merge ( y, x) , z) ; } else { val[ value] = ++ maxn; root = merge ( merge ( x, z) , y) ; } } void reverse ( int value, int op) { if ( ! op) { return ; } if ( op == 1 ) { int x, y, z, w; split ( root, val[ value] , x, z) ; split ( x, val[ value] - 1 , x, y) ; int t = get_num ( z, 1 ) ; split ( z, val[ t] , z, w) ; swap ( val[ y] , val[ z] ) ; root = merge ( merge ( x, z) , merge ( y, w) ) ; } else { int x, y, z, w; split ( root, val[ value] - 1 , x, z) ; split ( z, val[ value] , z, w) ; int t = get_num ( x, sz[ x] ) ; split ( x, val[ t] - 1 , x, y) ; swap ( val[ y] , val[ z] ) ; root = merge ( merge ( x, z) , merge ( y, w) ) ; } } int get_rank ( int value) { int x, y, ans; split ( root, val[ value] - 1 , x, y) ; ans = sz[ x] ; root = merge ( x, y) ; return ans; }
} tree; int main ( ) { int n, m; scanf ( "%d %d" , & n, & m) ; minn = 1 , maxn = n; for ( int i = 1 , x; i <= n; i++ ) { scanf ( "%d" , & x) ; tree. insert ( x, i) ; } char op[ 10 ] ; for ( int i = 1 , s, t; i <= m; i++ ) { scanf ( "%s %d" , op, & s) ; if ( op[ 0 ] == 'T' ) { tree. update ( s, 1 ) ; } else if ( op[ 0 ] == 'B' ) { tree. update ( s, 0 ) ; } else if ( op[ 0 ] == 'I' ) { scanf ( "%d" , & t) ; tree. reverse ( s, t) ; } else if ( op[ 0 ] == 'A' ) { printf ( "%d\n" , tree. get_rank ( s) ) ; } else { printf ( "%d\n" , tree. get_num ( s) ) ; } } return 0 ;
}