模板:
#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 ( "" ) ;
}
}
}