Splay 每个节点维护一个区间。
1 /************************************************************** 2 Problem: 3595 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:5428 ms 7 Memory:56020 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <map> 12 #define N 2000000 13 using namespace std; 14 15 map<int,int> atob, btoa; 16 map<int,int> rng_id; 17 18 struct Splay { 19 int son[N][2], pre[N], xlf[N], xrg[N], siz[N], root, ntot; 20 21 int newnode( int p, int lf, int rg ) { 22 if( lf>rg ) return 0; 23 int nd = ++ntot; 24 son[nd][0] = son[nd][1] = 0; 25 pre[nd] = p; 26 xlf[nd] = lf; 27 xrg[nd] = rg; 28 siz[nd] = rg-lf+1; 29 return nd; 30 } 31 void update( int nd ) { 32 siz[nd] = siz[son[nd][0]]+siz[son[nd][1]]+(xrg[nd]-xlf[nd]+1); 33 } 34 void rotate( int nd, int d ) { 35 int p=pre[nd]; 36 int s=son[nd][!d]; 37 int ss=son[s][d]; 38 39 son[nd][!d] = ss; 40 son[s][d] = nd; 41 if( p ) son[p][nd==son[p][1]]=s; 42 else root=s; 43 44 pre[nd] = s; 45 pre[s] = p; 46 if( ss ) pre[ss] = nd; 47 48 update( nd ); 49 update( s ); 50 } 51 void splay( int nd, int top=0 ) { 52 while( pre[nd]!=top ) { 53 int p=pre[nd]; 54 int nl=nd==son[p][0]; 55 if( pre[p]==top ) { 56 rotate( p, nl ); 57 } else { 58 int pp=pre[p]; 59 int pl=p==son[pp][0]; 60 if( nl==pl ) { 61 rotate( pp, pl ); 62 rotate( p, nl ); 63 } else { 64 rotate( p, nl ); 65 rotate( pp, pl ); 66 } 67 } 68 } 69 } 70 void init( int lf, int rg ) { 71 ntot = 0; 72 root = newnode( 0, lf, rg ); 73 rng_id[rg] = root; 74 } 75 void make_one( int nd ) { 76 int lnd, rnd; 77 splay( nd ); 78 lnd = son[nd][0]; 79 rnd = son[nd][1]; 80 while( son[lnd][1] ) lnd=son[lnd][1]; 81 while( son[rnd][0] ) rnd=son[rnd][0]; 82 if( lnd && rnd ) { 83 splay( lnd ); 84 splay( rnd, lnd ); 85 } else if( lnd ) { 86 splay( lnd ); 87 } else if( rnd ) { 88 splay( rnd ); 89 } 90 } 91 void split( int nd, int pos ) { 92 if( xlf[nd]==xrg[nd] ) return; 93 make_one( nd ); 94 int lnd, rnd; 95 lnd = newnode( 0, xlf[nd], pos-1 ); 96 rnd = newnode( 0, pos+1, xrg[nd] ); 97 son[nd][0] = lnd; 98 son[nd][1] = rnd; 99 if( lnd ) { 100 pre[lnd] = nd; 101 rng_id[pos-1] = lnd; 102 } 103 if( rnd ) { 104 pre[rnd] = nd; 105 rng_id[xrg[nd]] = rnd; 106 } 107 rng_id[pos] = nd; 108 xlf[nd] = xrg[nd] = pos; 109 update( nd ); 110 splay( nd ); 111 } 112 void erase( int nd ) { 113 make_one( nd ); 114 int p=pre[nd]; 115 pre[nd] = 0; 116 if( p ) { 117 son[p][ nd==son[p][1] ] = 0; 118 pre[nd] = 0; 119 update( p ); 120 splay( p ); 121 } else { 122 root = 0; 123 pre[nd] = 0; 124 } 125 } 126 void push_front( int nn ) { 127 if( !root ) { 128 root = nn; 129 return; 130 } 131 int nd=root; 132 while( son[nd][0] ) nd=son[nd][0]; 133 son[nd][0] = nn; 134 pre[nn] = nd; 135 splay( nn ); 136 } 137 void push_back( int nn ) { 138 if( !root ) { 139 root = nn; 140 return; 141 } 142 int nd=root; 143 while( son[nd][1] ) nd=son[nd][1]; 144 son[nd][1] = nn; 145 pre[nn] = nd; 146 splay(nn); 147 } 148 int rank( int nd ) { 149 int rt=siz[son[nd][0]]+1; 150 int nnd=nd; 151 while( pre[nd] ) { 152 int p=pre[nd]; 153 if( nd==son[p][1] ) rt += siz[son[p][0]]+(xrg[p]-xlf[p]+1); 154 nd=p; 155 } 156 splay(nnd); 157 return rt; 158 } 159 int nth( int k ) { 160 int nd=root; 161 while(1) { 162 int ls=siz[son[nd][0]]; 163 int lcs=ls+(xrg[nd]-xlf[nd]+1); 164 if( k<=ls ) { 165 nd = son[nd][0]; 166 } else if( k<=lcs ) { 167 int rt = xlf[nd]+k-ls-1; 168 splay( nd ); 169 return rt; 170 } else { 171 k -= lcs; 172 nd = son[nd][1]; 173 } 174 } 175 } 176 }T; 177 178 int n, m; 179 int main() { 180 scanf( "%d%d", &n, &m ); 181 T.init( 1, n ); 182 int la = 0; 183 for( int i=1; i<=m; i++ ) { 184 int opt, x, y; 185 scanf( "%d%d", &opt, &x ); 186 x -= la; 187 if( opt==1 ) { 188 scanf( "%d", &y ); 189 y -= la; 190 int pos = btoa.count(x) ? btoa[x] : x; 191 atob[pos] = y; 192 btoa[y] = pos; 193 int nd= rng_id.lower_bound( pos )->second; 194 T.split( nd, pos ); 195 printf( "%d\n", la=T.rank(nd) ); 196 } else if( opt==2 ) { 197 int pos = btoa.count(x) ? btoa[x] : x; 198 int nd=rng_id.lower_bound( pos )->second; 199 T.split( nd, pos ); 200 printf( "%d\n", la=T.rank(nd) ); 201 T.erase( nd ); 202 T.push_front( nd ); 203 } else if( opt==3 ) { 204 int pos = btoa.count(x) ? btoa[x] : x; 205 int nd = rng_id.lower_bound( pos )->second; 206 T.split( nd, pos ); 207 printf( "%d\n", la=T.rank(nd) ); 208 T.erase( nd ); 209 T.push_back( nd ); 210 } else { 211 int pos=T.nth(x); 212 int b = atob.count(pos) ? atob[pos] : pos; 213 printf( "%d\n", la=b ); 214 } 215 } 216 }