BZOJ 1861 [Zjoi2006]Book 书架 ——Splay
【题目分析】
模板题目。
首尾两个虚拟结点,十分方便操作。
【代码】
#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); } } }