题目
思路
首先,我们可以用一个map存一下每一个key值对应的点的编号和每一个点对应的key;用两个变量记录出现过的最大的key和最小的key。
- Q操作,就是普通的查询,得到key值后输出对应的点编号即可
- T操作,将原本的点删去,然后插入一个key为(Minkey - 1)的点,即把此点放到第一个。更新即可。
- B操作,和T操作类似,插入key为(Maxkey + 1)的点。
- A操作,也是普通的查询,输入s点对应key值的排名-1即可
- I操作,因为只会与前一位或后一位的点交换,将这两个点得key值交换即可。
Code:
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 160005
#define LL long long
#define Mod 1000000
#define Int_Max 2147483647
#define INF 0x3f3f3f3f
#define Int register int
using namespace std;
struct node
{
int Size, Key, l, r, Rank, Xiu;
}Point[MAXN];
int Num;
map<int, int> Pointof;
int Max(int x,int y)
{
return x > y ? x : y;
}
int Abs(int x)
{
if (x > 0)
return x;
return -x;
}
int Min(int x,int y)
{
return x < y ? x : y;
}
inline void read(int &x)
{
x = 0;
int f = 1;
char s = getchar();
while (s < '0' || s > '9')
{
if (s == '-')
f = -1;
s = getchar();
}
while (s >= '0' && s <= '9')
{
x = (x << 3) + (x << 1) + (s ^ 48);
s = getchar();
}
x *= f;
}
int GetHash()
{
static int Seed = 122520;
Seed = (int)Seed * 520122ll % Int_Max;
return Seed;
}
void Update(int x)
{
Point[x].Size = Point[Point[x].l].Size + Point[Point[x].r].Size + Point[x].Rank;
}
void Lturn(int &x)
{
int rson = Point[x].r;
Point[x].r = Point[rson].l;
Point[rson].l = x;
Point[rson].Size = Point[x].Size;
Update( x );
x = rson;
}
void Rturn(int &x)
{
int lson = Point[x].l;
Point[x].l = Point[lson].r;
Point[lson].r = x;
Point[lson].Size = Point[x].Size;
Update( x );
x = lson;
}
void Insert(int &x,int val)
{
if (! x)
{
x = ++ Num;
Point[x].Size = Point[x].Rank = 1;
Point[x].Key = val;
Point[x].Xiu = rand();
return ;
}
Point[x].Size ++;
if (Point[x].Key == val)
Point[x].Rank ++;
else if (val > Point[x].Key)
{
Insert(Point[x].r, val);
if (Point[Point[x].r].Xiu < Point[x].Xiu)
Lturn( x );
}
else
{
Insert(Point[x].l, val);
if (Point[Point[x].l].Xiu < Point[x].Xiu)
Rturn( x );
}
}
void Delete(int &x,int val)
{
if (! x)
return ;
if (Point[x].Key == val)
{
if (Point[x].Rank > 1)
Point[x].Rank --, Point[x].Size --;
else
{
if (! Point[x].l || ! Point[x].r)
x = Point[x].l + Point[x].r;
else if (Point[Point[x].l].Xiu < Point[Point[x].r].Xiu)
Rturn( x ), Delete(x, val);
else Lturn( x ), Delete(x, val);
}
}
else if (val > Point[x].Key)
Point[x].Size --, Delete(Point[x].r, val);
else Point[x].Size --, Delete(Point[x].l, val);
}
int GetRank(int x,int val)
{
if (! x)
return 0;
if (Point[x].Key == val)
return Point[Point[x].l].Size + 1;
if (val > Point[x].Key)
return Point[Point[x].l].Size + Point[x].Rank + GetRank(Point[x].r, val);
else return GetRank(Point[x].l, val);
}
int GetXth(int x,int val)
{
if (! x)
return 0;
if (val <= Point[Point[x].l].Size)
return GetXth(Point[x].l, val);
val -= Point[Point[x].l].Size;
if (val <= Point[x].Rank)
return Point[x].Key;
val -= Point[x].Rank;
return GetXth(Point[x].r, val);
}
int FindHead(int x,int val)
{
if (! x)
return -INF;
if (Point[x].Key > val)
return FindHead(Point[x].l, val);
else return Max(Point[x].Key, FindHead(Point[x].r, val));
}
int FindBack(int x,int val)
{
if (! x)
return INF;
if (Point[x].Key <= val)
return FindBack(Point[x].r, val);
else return Min(Point[x].Key, FindBack(Point[x].l, val));
}
inline void Swap(int &x,int &y)
{
int temp = x;
x = y;
y = temp;
}
int Order[MAXN];
int Root, Maxkey, Minkey;
int main()
{
srand(*new unsigned);
int n, m;
read( n ); read( m );
Maxkey = n, Minkey = 1;
for (Int i = 1; i <= n; ++ i)
{
int Bh;
read( Bh );
Insert(Root, i);
Order[Bh] = i;
Pointof[i] = Bh;
}
for (Int i = 1; i <= m; ++ i)
{
char Or[10];
scanf("%s", Or);
switch( Or[0] )
{
case 'Q':
{
int k;
read( k );
int Get = GetXth(Root, k);
printf("%d\n", Pointof[Get]);
break;
}
case 'T':
{
int k;
read( k );
Delete(Root, Order[k]);
Insert(Root, -- Minkey);
Order[k] = Minkey;
Pointof[Minkey] = k;
break;
}
case 'B':
{
int k;
read( k );
Delete(Root, Order[k]);
Insert(Root, ++ Maxkey);
Order[k] = Maxkey;
Pointof[Maxkey] = k;
break;
}
case 'A':
{
int k;
read( k );
int Get = GetRank(Root, Order[k]);
printf("%d\n", Get - 1);
break;
}
case 'I':
{
int k, t;
read( k ); read( t );
int Want = GetRank(Root, Order[k]);
int KK = GetXth(Root, Want + t);
int PP = Pointof[KK];
Swap(Pointof[Order[k]], Pointof[KK]);
Swap(Order[k], Order[PP]);
break;
}
}
}
return 0;
}