題目點這裏 原來的題解點這裏 。。Treap+Map寫的。。。
。。然後聽說scoi的評測雞很傲嬌。。。。當場是卡了map的。。。。
所以我就重新寫了雙Treap。。。一個維護編號一個維護排名。。。。。。
叫bzoj比map慢了幾十ms = =因爲有-O2?
rank3是的評測結果 rank4和rank5目測都是直接交的我的代碼吧 = =||||
然後rank6就是這份代碼的評測結果了。。。
回綿陽了以後用cena測測試試。。。按理說手寫應該還是能比STL快的?
(ac代碼有問題 僅供參考!!)
#include <cstdio>
#include <iostream>
#include <cstdlib>
using namespace std;
int read()
{
int n = 0, sign = 1; char c = getchar();
while(c > '9' || c < '0') {if(c == '-') sign = -1; c = getchar();}
while(c >= '0' && c <= '9') {n = n*10 + c-'0'; c = getchar(); }
return sign * n;
}
const int inf = 0x3f3f3f3f;
int cnt = 1, tot = 1;
struct Treap{
struct node{
node *lc, *rc;
int s, id, r, L, R;
}t[300055], *null, *root;
inline void init()
{
null = &t[0]; null -> lc = null -> rc = null;
null -> s = 0; null -> id = null -> L = null -> R = null -> r = -inf;
root = null;
}
inline node *NewNode(int index, int L, int R)
{
t[cnt].lc = t[cnt].rc = null; t[cnt].r = rand();
t[cnt].id = index; t[cnt].L = L; t[cnt].R = R; t[cnt].s = R - L + 1;
return &t[cnt++];
}
inline void pushup(node *&p){ p->s = p->lc->s + p->rc->s + (p->R-p->L+1);}
inline void maintain(node *&p)
{
if(p->lc->r > p->r)
{
node *temp = p -> lc;
p -> lc = temp -> rc;
temp -> rc = p;
pushup(p); p = temp;
}
else if(p->rc->r > p->r)
{
node *temp = p -> rc;
p -> rc = temp -> lc;
temp -> lc = p;
pushup(p); p = temp;
}
pushup(p);
}
void insert(node *&p, int L, int R, int index)
{
if(p == null)
{
p = NewNode(index, L, R);
return;
}
if(R < p -> L) insert(p -> lc, L, R, index);
else insert(p -> rc, L, R, index);
maintain(p);
}
void merge(node *&ne, node *p, node *q)
{
if(p == null || q == null)
{
ne = p == null ? q : p;
return;
}
if(p->r > q->r) { ne = p; merge(ne->rc, p->rc, q); }
else{ ne = q; merge(ne->lc, p, q->lc); }
pushup(ne);
}
void del(node *&p, int pos)
{
if(p == null) return;
if(p->L <= pos && pos <= p->R)
{
if(p->L == p->R) merge(p, p->lc, p->rc);
else if(p->L == pos) { ++ p -> L; ++ p -> id; pushup(p); }
else if(p->R == pos) { -- p -> R; pushup(p); }
else
{
insert(p -> rc, pos + 1, p -> R, pos + 1);
p -> R = pos - 1; pushup(p);
}
return;
}
if(p->L > pos) del(p -> lc, pos);
else del(p -> rc, pos); maintain(p);
}
int getrank(node *p, int pos)
{
if(p == null) return 0;
if(p->L <= pos && pos <= p->R) return (pos - p->L + 1) + p->lc->s;
if(p->L > pos) return getrank(p->lc, pos);
else return getrank(p->rc, pos) + p->lc->s + (p->R - p->L + 1);
}
int getindex(node *p, int k)
{
if(p == null) return 0;
int lsize = p->lc->s;
if(k <= lsize) return getindex(p->lc, k);
if(lsize < k && lsize + (p->R - p->L + 1) >= k)
{
if(p->L == p->R) return p->id;
else return k-lsize-1 + p->L;
}
else return getindex(p->rc, k - lsize - (p->R - p->L + 1));
}
}t;
struct Map{
struct node{
node *lc, *rc;
int r, id, rank;
}t[300055], *null, *root;
inline void init()
{
null = &t[0]; null -> lc = null -> rc = null;
null -> rank = null -> r = -inf; root = null;
}
inline node *NewNode(int index, int rank)
{
t[tot].lc = t[tot].rc = null; t[tot].r = rand();
t[tot].id = index; t[tot].rank = rank; return &t[tot++];
}
inline void maintain(node *&p)
{
if(p->lc->r > p->r)
{
node *temp = p -> lc;
p -> lc = temp -> rc;
temp -> rc = p; p = temp;
}
else if(p->rc->r > p->r)
{
node *temp = p -> rc;
p -> rc = temp -> lc;
temp -> lc = p; p = temp;
}
}
void insert(node *&p, int index, int rank)
{
if(p == null)
{
p = NewNode(index, rank);
return;
}
if(index == p -> id) p -> rank = rank;
else if(index < p -> id) insert(p -> lc, index, rank);
else insert(p -> rc, index, rank);
maintain(p);
}
int find(node *p, int index)
{
if(p == null) return 0;
if(p -> id == index) return p -> rank;
if(p -> id > index) return find(p -> lc, index);
return find(p -> rc, index);
}
void remove(node *p, int index)
{
if(p == null) return;
if(p -> id == index) p -> rank = 0;
else if(p -> id > index) remove(p -> lc, index);
else remove(p -> rc, index);
}
}m;
int N, M;
int main()
{
srand(20150233); t.init(); m.init();
N = read(); t.insert(t.root, 1, N, 1);
int mmin = 0, mmax = N, a = 0;
for(M = read(); M--; )
{
int sign = read(), x = read(); x -= a;
if(sign == 1)
{
int y = read(); y -= a;
int pos = m.find(m.root, x); if(!pos) pos = x;
printf("%d\n", a = t.getrank(t.root, pos));
t.del(t.root, pos);
t.insert(t.root, pos, pos, y);
m.remove(m.root, x); m.insert(m.root, y, pos);
}
else if(sign == 2)
{
int pos = m.find(m.root, x); if(!pos) pos = x;
printf("%d\n", a = t.getrank(t.root, pos));
t.del(t.root, pos); m.insert(m.root, x, pos = --mmin);
t.insert(t.root, pos, pos, x);
}
else if(sign == 3)
{
int pos = m.find(m.root, x); if(!pos) pos = x;
printf("%d\n", a = t.getrank(t.root, pos));
t.del(t.root, pos); m.insert(m.root, x, pos = ++mmax);
t.insert(t.root, pos, pos, x);
}
else printf("%d\n", a = t.getindex(t.root, x));
}
return 0;
}