【题目分析】
模板题目。
首尾两个虚拟结点,十分方便操作。
【代码】
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 500005
#define inf 0x3f3f3f3f
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define L ch[o][0]
#define R ch[o][1]
void Finout()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
}
int Getint()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int n,m;
struct Bit_Tree{
int a[maxn],b[maxn];
void add(int x,int y,int z)
{
for (int i=x;i<=n;i+=i&(-i)) b[i]+=z;
for (int i=y+1;i<=n;i+=i&(-i)) b[i]-=z;
for (int i=x;i<=n;i+=i&(-i)) a[i]+=(n-x)*z;
for (int i=y+1;i<=n;i+=i&(-i)) a[i]-=(n-y-1)*z;
}
int getsum(int x)
{
int ret=0,tmp=0;
for (int i=x;i;i-=i&(-i)) ret+=a[i];
for (int i=x;i;i-=i&(-i)) tmp+=b[i];
return ret-(n-x-1)*tmp;
}
void init()
{
memset(a,0,sizeof a);
memset(b,0,sizeof b);
}
}t;
int rt=0,a[maxn],s,T,id[maxn],cnt=0;
char opt[10];
int num[maxn],ch[maxn][2],siz[maxn],fa[maxn],list[maxn];
void update(int o)
{
siz[o]=siz[L]+siz[R]+1;
}
void rot(int x,int &k)
{
// cout<<"rot"<<x<<endl;
int y=fa[x],z=fa[y],l,r;
if (ch[y][0]==x) l=0; else l=1;
r=l^1;
if (y==k) k=x;
else
{
if (ch[z][0]==y) ch[z][0]=x;
else ch[z][1]=x;
}
fa[x]=z;
fa[y]=x;
fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];
ch[x][r]=y;
update(y); update(x);
}
void splay(int x,int &k)
{
int y,z;
while (x!=k)
{
y=fa[x];z=fa[y];
if (y!=k)
{
if ((ch[z][0]==y)^(ch[y][0]==x)) rot(x,k);
else rot(y,k);
}
rot(x,k);
}
}
void ins(int & o,int x,int lst)
{
if (!o)
{
o=++cnt;
fa[o]=lst;
num[o]=x;
siz[o]=1;
list[o]=a[x-1];
splay(o,rt);
return ;
}
if (x<num[o]) ins(ch[o][0],x,o);
else ins(ch[o][1],x,o);
update(o);
}
int find(int o,int x)
{
// cout<<"qnum"<<num[o]<<" "<<x<<endl;
if (siz[L]+1==x) return o;
if (siz[L]>=x) return find(L,x);
else return find(R,x-siz[L]-1);
}
void print(int o)
{
if (!o) return ;
print(L);
// cout<<"now is "<<o<<endl;
// cout<<L<<" "<<R<<endl;
// cout<<num[o]<<" "<<siz[o]<<endl;
cout<<num[o]<<" ";
print(R);
}
void Mov(int o,int k)
{
splay(o,rt);
int pre=find(rt,siz[L]),nxt=find(rt,siz[L]+2);
splay(pre,rt); splay(nxt,ch[rt][1]);
ch[nxt][0]=0; fa[o]=0;
update(nxt); update(pre);
splay(nxt,rt);
pre=find(rt,k-1);nxt=find(rt,k);
splay(pre,rt); splay(nxt,ch[rt][1]);
ch[nxt][0]=o; fa[o]=nxt;
splay(o,rt);
}
int main()
{
Finout();
scanf("%d%d",&n,&m);
F(i,1,n) scanf("%d",&a[i]),id[a[i]]=i+1;
F(i,0,n+1) ins(rt,i,0);
// print(rt);
// cout<<rt<<endl;
F(i,1,m)
{
// print(rt);
// cout<<endl;
scanf("%s",opt);
scanf("%d",&s);
if (opt[0]=='Q')
{
// cout<<"QUERY"<<endl;
printf("%d\n",a[find(rt,s+1)-1]);
}
else if (opt[0]=='A')
{
// cout<<"ASK"<<endl;
splay(id[s],rt);
printf("%d\n",siz[ch[rt][0]]-1);
}
else if (opt[0]=='T')
{
// cout<<"TOP"<<endl;
Mov(id[s],1+1);
}
else if (opt[0]=='B')
{
// cout<<"BOT"<<endl;
Mov(id[s],n+1);
}
else
{
T=Getint();
splay(id[s],rt);
int tmp=siz[ch[rt][0]];
Mov(id[s],tmp+T+1);
}
}
}