hdoj 2871
poj 3667 hotel套了个马甲
线段树基本操作不用变,按分配内存先后分别标记每个内存块的编号,增加一个查找某点所属内存块的编号的函数
记录每个内存块的起始位置和结束位置,然后维护一颗BST,以起始编号为主键,求第k大即可
线段树+SBT
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits>
#include <set>
#include <string>
#include <sstream>
#include <utility>
#include <ctime>
using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::getline;
using std::make_pair;
using std::greater;
const int MAXN(50010);
struct ELE
{
int key1, key2;
ELE(int tk1 = 0, int tk2 = 0): key1(tk1), key2(tk2)
{}
friend bool operator < (const ELE &op1, const ELE &op2)
{
return op1.key1 < op2.key1;
}
friend bool operator > (const ELE &op1, const ELE &op2)
{
return op1.key1 > op2.key1;
}
friend bool operator >= (const ELE &op1, const ELE &op2)
{
return op1.key1 >= op2.key1;
}
friend bool operator == (const ELE &op1, const ELE &op2)
{
return op1.key1 == op2.key1;
}
friend ELE operator +(ELE op1, int op2)
{
op1.key1 += op2;
return op1;
}
};
template<typename T>
struct SBT
{
struct NODE
{
T key;
int size;
NODE *left;
NODE *right;
};
NODE pool[MAXN];
NODE *root, *NIL, *rear;
T tkey;
void init()
{
NIL = pool;
rear = pool+1;
NIL->size = 0;
NIL->left = NIL;
NIL->right = NIL;
root = NIL;
}
NODE *newnode(const T &value)
{
rear->key = value;
rear->left = NIL;
rear->right = NIL;
rear->size = 1;
return rear++;
}
void left_rotate(NODE *&sour)
{
NODE *temp = sour->right;
sour->right = temp->left;
temp->left = sour;
temp->size = sour->size;
sour->size = sour->left->size+sour->right->size+1;
sour = temp;
}
void right_rotate(NODE *&sour)
{
NODE *temp = sour->left;
sour->left = temp->right;
temp->right = sour;
temp->size = sour->size;
sour->size = sour->left->size+sour->right->size+1;
sour = temp;
}
void maintain(NODE *&sour, bool flag)
{
if(flag == false)
{
if(sour->left->left->size > sour->right->size)
{
right_rotate(sour);
}
else
if(sour->left->right->size > sour->right->size)
{
left_rotate(sour->left);
right_rotate(sour);
}
else
return;
}
else
{
if(sour->right->right->size > sour->left->size)
{
left_rotate(sour);
}
else
if(sour->right->left->size > sour->left->size)
{
right_rotate(sour->right);
left_rotate(sour);
}
else
return;
}
maintain(sour->right, true);
maintain(sour->left, false);
maintain(sour, true);
maintain(sour, false);
}
void insert(const T &value)
{
tkey = value;
insert_(root);
}
void insert_(NODE *&sour)
{
if(sour == NIL)
{
sour = newnode(tkey);
return;
}
++sour->size;
if(tkey < sour->key)
insert_(sour->left);
else
insert_(sour->right);
maintain(sour, tkey >= sour->key);
}
void erase(T value)
{
erase_(root, value);
}
T erase_(NODE *&sour, const T &value)
{
--sour->size;
if(value == sour->key || (value < sour->key && sour->left == NIL) || (value > sour->key && sour->right == NIL))
{
T temp = sour->key;
if(sour->left == NIL || sour->right == NIL)
sour = sour->left-NIL+sour->right;
else
sour->key = erase_(sour->left, value+1);
return temp;
}
if(value < sour->key)
return erase_(sour->left, value);
else
return erase_(sour->right, value);
}
NODE *select(int r)
{
NODE *sour = root;
while(sour != NIL && r != sour->left->size+1)
{
if(r <= sour->left->size)
sour = sour->left;
else
{
r -= sour->left->size+1;
sour = sour->right;
}
}
return sour;
}
};
struct SEGMENT_TREE
{
int cover[MAXN << 2], lsum[MAXN << 2], rsum[MAXN << 2], msum[MAXN << 2];
inline int left_son(int root)
{
return root << 1;
}
inline int right_son(int root)
{
return (root << 1)|1;
}
void push_up(int root, int l1, int l2)
{
lsum[root] = lsum[left_son(root)];
rsum[root] = rsum[right_son(root)];
if(lsum[root] == l1)
lsum[root] += lsum[right_son(root)];
if(rsum[root] == l2)
rsum[root] += rsum[left_son(root)];
msum[root] = max(rsum[left_son(root)]+lsum[right_son(root)], max(msum[left_son(root)], msum[right_son(root)]));
}
void push_down(int root, int l1, int l2)
{
if(cover[root] != -1)
{
cover[left_son(root)] = cover[right_son(root)] = cover[root];
lsum[left_son(root)] = rsum[left_son(root)] = msum[left_son(root)] = cover[root]? 0: l1;
lsum[right_son(root)] = rsum[right_son(root)] = msum[right_son(root)] = cover[root]? 0: l2;
cover[root] = -1;
}
}
void build_tree(int l, int r, int root)
{
cover[root] = -1;
lsum[root] = rsum[root] = msum[root] = r-l+1;
if(l == r)
return;
int m = (l+r) >> 1;
build_tree(l, m, left_son(root));
build_tree(m+1, r, right_son(root));
}
int allocate(int op, int l, int r, int root)
{
if(l == r)
return l;
int m = (l+r) >> 1;
push_down(root, m-l+1, r-m);
if(op <= msum[left_son(root)])
return allocate(op, l, m, left_son(root));
else
if(op <= rsum[left_son(root)]+lsum[right_son(root)])
return m-rsum[left_son(root)]+1;
else
return allocate(op, m+1, r, right_son(root));
}
void updata(int op, int ql, int qr, int l, int r, int root)
{
if(ql <= l && qr >= r)
{
lsum[root] = rsum[root] = msum[root] = op? 0: r-l+1;
cover[root] = op;
return;
}
int m = (l+r) >> 1;
push_down(root, m-l+1, r-m);
if(ql <= m)
updata(op, ql, qr, l, m, left_son(root));
if(qr > m)
updata(op, ql, qr, m+1, r, right_son(root));
push_up(root, m-l+1, r-m);
}
int query(int op, int l, int r, int root)
{
if(cover[root] != -1)
return cover[root];
if(l == r)
return 0;
int m = (l+r) >> 1;
if(op <= m)
return query(op, l, m, left_son(root));
else
return query(op, m+1, r, right_son(root));
}
};
SEGMENT_TREE st;
SBT<ELE> sbt;
int s[MAXN], e[MAXN];
int count;
char str[10];
int main()
{
int n, m, temp;
int op;
while(~scanf("%d%d", &n, &m))
{
st.build_tree(1, n, 1);
sbt.init();
count = 0;
for(int i = 0; i < m; ++i)
{
scanf("%s", str);
switch(str[0])
{
case 'R': st.updata(0, 1, n, 1, n, 1);
printf("Reset Now\n");
sbt.init();
break;
case 'N': scanf("%d", &op);
if(op > st.msum[1])
{
printf("Reject New\n");
}
else
{
temp = st.allocate(op, 1, n, 1);
printf("New at %d\n", temp);
++count;
s[count] = temp;
e[count] = temp+op-1;
st.updata(count, s[count], e[count], 1, n, 1);
sbt.insert(ELE(s[count], e[count]));
}
break;
case 'F': scanf("%d", &op);
temp = st.query(op, 1, n, 1);
if(temp)
{
printf("Free from %d to %d\n", s[temp], e[temp]);
st.updata(0, s[temp], e[temp], 1, n, 1);
sbt.erase(ELE(s[temp], e[temp]));
}
else
{
printf("Reject Free\n");
}
break;
case 'G': scanf("%d", &op);
SBT<ELE>::NODE *ret = sbt.select(op);
if(ret == sbt.NIL)
{
printf("Reject Get\n");
}
else
{
printf("Get at %d\n", ret->key.key1);
}
break;
}
}
printf("\n");
}
return 0;
}
splay+treap
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
#include <cctype>
#include <utility>
#include <map>
#include <string>
#include <climits>
#include <set>
#include <string>
#include <sstream>
#include <utility>
#include <ctime>
using std::priority_queue;
using std::vector;
using std::swap;
using std::stack;
using std::sort;
using std::max;
using std::min;
using std::pair;
using std::map;
using std::string;
using std::cin;
using std::cout;
using std::set;
using std::queue;
using std::string;
using std::istringstream;
using std::getline;
using std::make_pair;
using std::greater;
const int MAXN(50010);
const int INFI((INT_MAX-1) >> 1);
int n;
struct SPLAY_TREE
{
struct NODE
{
int cover;
int key;
int lsum, rsum, msum;
int color;
int size;
NODE *fa;
NODE *ch[2];
};
NODE pool[MAXN];
NODE *root, *NIL, *rear;
void init()
{
rear = pool+1;
NIL = pool;
NIL->key = -1;
NIL->cover = -1;
NIL->size = NIL->lsum = NIL->rsum = NIL->msum = 0;
NIL->color = MAXN;
NIL->ch[0] = NIL->ch[1] = NIL->fa = NIL;
newnode(root, NIL, 0, MAXN);
newnode(root->ch[1], root, n+1, MAXN);
build_tree(root->ch[1]->ch[0], root->ch[1], 1, n);
push_up(root->ch[1]);
push_up(root);
}
void newnode(NODE *&sour, NODE *f, int tk, int tc)
{
rear->key = tk;
rear->color = tc;
rear->cover = -1;
rear->size = 1;
rear->fa = f;
rear->ch[0] = rear->ch[1] = NIL;
sour = rear++;
}
void push_up(NODE *sour)
{
sour->lsum = sour->ch[0]->lsum;
sour->rsum = sour->ch[1]->rsum;
sour->msum = 0;
if(sour->color == 0)
{
if(sour->lsum == sour->ch[0]->size)
sour->lsum += 1+sour->ch[1]->lsum;
if(sour->rsum == sour->ch[1]->size)
sour->rsum += 1+sour->ch[0]->rsum;
sour->msum = sour->ch[0]->rsum+sour->ch[1]->lsum+1;
}
sour->msum = max(sour->msum, max(sour->ch[0]->msum, sour->ch[1]->msum));
sour->size = sour->ch[0]->size+sour->ch[1]->size+1;
}
void push_down(NODE *sour)
{
if(sour->cover != -1)
{
sour->ch[0]->cover = sour->ch[0]->color = sour->cover;
sour->ch[1]->cover = sour->ch[1]->color = sour->cover;
sour->ch[0]->lsum = sour->ch[0]->rsum = sour->ch[0]->msum = sour->cover? 0: sour->ch[0]->size;
sour->ch[1]->lsum = sour->ch[1]->rsum = sour->ch[1]->msum = sour->cover? 0: sour->ch[1]->size;
sour->cover = -1;
}
}
void build_tree(NODE *&sour, NODE *f, int l, int r)
{
if(l > r)
return;
int m = (l+r) >> 1;
newnode(sour, f, m, 0);
build_tree(sour->ch[0], sour, l, m-1);
build_tree(sour->ch[1], sour, m+1, r);
push_up(sour);
}
void rotate(NODE *&sour, int flag)
{
NODE *f = sour->fa;
push_down(f);
push_down(sour);
f->ch[!flag] = sour->ch[flag];
sour->ch[flag]->fa = f;
sour->fa = f->fa;
if(f->fa != NIL)
f->fa->ch[f->fa->ch[1] == f] = sour;
sour->ch[flag] = f;
f->fa = sour;
push_up(f);
}
void splay(NODE *sour, NODE *goal)
{
push_down(sour);
while(sour->fa != goal)
{
if(sour->fa->fa == goal)
rotate(sour, sour->fa->ch[0] == sour);
else
{
NODE *f = sour->fa;
int flag = (f->fa->ch[0] == f);
if(f->ch[flag] == sour)
rotate(sour, !flag);
else
rotate(f, flag);
rotate(sour, flag);
}
}
push_up(sour);
if(goal == NIL)
root = sour;
}
NODE *select(int r, NODE *sour)
{
push_down(sour);
while(sour != NIL && r != sour->ch[0]->size+1)
{
if(r <= sour->ch[0]->size)
sour = sour->ch[0];
else
{
r -= sour->ch[0]->size+1;
sour = sour->ch[1];
}
push_down(sour);
}
return sour;
}
NODE *find(int op, NODE *sour)
{
if(op > sour->msum)
return NIL;
push_down(sour);
NODE *ret;
while(sour != NIL)
{
if(op <= sour->ch[0]->msum)
sour = sour->ch[0];
else
if(sour->color == 0 && op <= sour->ch[0]->rsum+sour->ch[1]->lsum+1)
{
ret = select(sour->ch[0]->size-sour->ch[0]->rsum+1, sour);
break;
}
else
sour = sour->ch[1];
push_down(sour);
}
return ret;
}
NODE *allocate(int op)
{
NODE *sour;
sour = select(1, root);
splay(sour, NIL);
sour = select(n+2, root);
splay(sour, root);
sour = find(op, root->ch[1]->ch[0]);
return sour;
}
void change(int op, int ql, int qr)
{
NODE *sour;
sour = select(ql, root);
splay(sour, NIL);
sour = select(qr+2, root);
splay(sour, root);
sour = root->ch[1]->ch[0];
sour->color = sour->cover = op;
sour->lsum = sour->rsum = sour->msum = op? 0: sour->size;
push_up(root->ch[1]);
push_up(root);
}
int query(int op)
{
NODE *sour = select(op+1, root);
splay(sour, NIL);
return root->color;
}
};
struct TREAP
{
struct NODE
{
int key;
int fix;
int size;
NODE *left, *right;
};
NODE pool[MAXN];
NODE *root, *NIL, *rear;
int tkey;
void init()
{
rear = pool+1;
NIL = pool;
NIL->left = NIL;
NIL->right = NIL;
NIL->size = 0;
NIL->fix = INFI;
root = NIL;
}
void newnode(NODE *&sour, int value)
{
rear->key = value;
rear->fix = rand();
rear->size = 1;
rear->left = rear->right = NIL;
sour = rear++;
}
void left_rotate(NODE *&sour)
{
NODE *temp = sour->right;
sour->right = temp->left;
temp->left = sour;
temp->size = sour->size;
sour->size = sour->left->size+sour->right->size+1;
sour = temp;
}
void right_rotate(NODE *&sour)
{
NODE *temp = sour->left;
sour->left = temp->right;
temp->right = sour;
temp->size = sour->size;
sour->size = sour->left->size+sour->right->size+1;
sour = temp;
}
void insert(int value)
{
tkey = value;
insert_(root);
}
void insert_(NODE *&sour)
{
if(sour == NIL)
{
newnode(sour, tkey);
return;
}
++sour->size;
if(tkey < sour->key)
{
insert_(sour->left);
if(sour->left->fix < sour->fix)
right_rotate(sour);
}
else
{
insert_(sour->right);
if(sour->right->fix < sour->fix)
left_rotate(sour);
}
}
void erase(int value)
{
erase_(root, value);
}
void erase_(NODE *&sour, int value)
{
if(value == sour->key)
{
if(sour->left == NIL || sour->right == NIL)
sour = sour->left-NIL+sour->right;
else
{
--sour->size;
if(sour->left->fix < sour->right->fix)
{
right_rotate(sour);
erase_(sour->right, value);
}
else
{
left_rotate(sour);
erase_(sour->left, value);
}
}
return;
}
--sour->size;
if(value < sour->key)
erase_(sour->left, value);
else
erase_(sour->right, value);
}
NODE *select(int r)
{
NODE *sour = root;
while(sour != NIL && r != sour->left->size+1)
{
if(r <= sour->left->size)
sour = sour->left;
else
{
r -= sour->left->size+1;
sour = sour->right;
}
}
return sour;
}
};
SPLAY_TREE splay;
TREAP treap;
int s[MAXN], e[MAXN];
int count;
char str[10];
int main()
{
int m, op;
while(~scanf("%d%d", &n, &m))
{
splay.init();
treap.init();
count = 0;
SPLAY_TREE::NODE *p1;
TREAP::NODE *p2;
int temp;
for(int i = 0; i < m; ++i)
{
scanf("%s", str);
switch(str[0])
{
case 'R': splay.change(0, 1, n);
treap.init();
count = 0;
printf("Reset Now\n");
break;
case 'N': scanf("%d", &op);
p1 = splay.allocate(op);
if(p1 != splay.NIL)
{
++count;
s[count] = p1->key;
e[count] = p1->key+op-1;
treap.insert(p1->key);
splay.change(count, s[count], e[count]);
printf("New at %d\n", p1->key);
}
else
printf("Reject New\n");
break;
case 'F': scanf("%d", &op);
temp = splay.query(op);
if(temp != 0)
{
treap.erase(s[temp]);
splay.change(0, s[temp], e[temp]);
printf("Free from %d to %d\n", s[temp], e[temp]);
}
else
printf("Reject Free\n");
break;
case 'G': scanf("%d", &op);
p2 = treap.select(op);
if(p2 != treap.NIL)
{
printf("Get at %d\n", p2->key);
}
else
printf("Reject Get\n");
break;
}
}
printf("\n");
}
return 0;
}