http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112
提高代码能力。。。
方法一:
线段树套平衡树,时间:O(m*lgn*lgn*lgn),空间:O(n*lgn)。
<pre name="code" class="cpp">#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN(50010);
template<typename T>
bool checkmin(T &a, const T &b){
return b < a? (a = b, true): false;
}
template<typename T>
bool checkmax(T &a, const T &b){
return b > a? (a = b, true): false;
}
struct RAND{
int rn[MAXN], si, n;
void init(int n){
this->n = n;
srand(2357);
for(int i = 0; i < n; ++i) rn[i] = rand();
si = 0;
}
int query(){
if(si >= n) si -= n;
return rn[si++];
}
} ra;
struct NODE1{
int ke, b, si;
NODE1 *ch[2];
} *NIL1;
struct POOL1{
NODE1 pool[MAXN*19], *last;
void init(){
last = pool;
}
NODE1 *all(int k){
last->ch[0] = last->ch[1] = NIL1;
last->ke = k;
last->b = ra.query();
last->si = 1;
return last++;
}
} pool1;
inline void rep(NODE1 *rt){
if(rt == NIL1) return;
rt->si = rt->ch[0]->si+rt->ch[1]->si+1;
}
void rot(NODE1 *&rt, int f){
NODE1 *s = rt->ch[f];
rt->ch[f] = s->ch[!f];
s->ch[!f] = rt;
rep(rt);
rep(s);
rt = s;
}
void Insert(NODE1 *&rt, int k){
if(rt == NIL1){
rt = pool1.all(k);
return;
}
int t = (k >= rt->ke);
Insert(rt->ch[t], k);
if(rt->ch[t]->b > rt->b) rot(rt, t);
rep(rt);
}
void Erase(NODE1 *&rt, int k){
if(rt->ke == k){
if(rt->ch[0] == NIL1 || rt->ch[1] == NIL1){
rt = rt->ch[rt->ch[0] == NIL1];
// rep(rt);
return;
}
int t = rt->ch[0]->b < rt->ch[1]->b;
rot(rt, t);