从一开始学离散化就对它没有半毛钱好感,感觉出这种题纯属恶心人。
可以将Top x全部取出来然后离散化,缩点。剩下的就是伸展了,不再赘述。
也有人拿线段树过,一直没有想明白. . .
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long #define _LL __int64 #define _INF 0x3f3f3f3f #define Mod 9999991 using namespace std; const int MAXN = 200100; struct N { //info int son[2],pre; //data int data; int sum; int ls,rs,s; }st[200100]; struct O { int ty; int x; }com[101000]; struct NNum { int num,w,site; }Num[201000],TNum[201000]; int Top_Num; int Top; void Updata(int root) { st[root].ls = 0,st[root].rs = 0; if(st[root].son[0] != -1) st[root].ls = st[st[root].son[0]].s; if(st[root].son[1] != -1) st[root].rs = st[st[root].son[1]].s; st[root].s = st[root].rs + st[root].ls + st[root].sum; } void Push_Down(int root) { ; } void Init(int &root,int s,int e,int pre) { if(s > e) return ; int mid = (s+e)>>1; root = Top++; st[root].data = Num[mid].num; st[root].sum = Num[mid].w; Num[mid].site = root; st[root].pre = pre; st[root].son[0] = -1,st[root].son[1] = -1; Init(st[root].son[0],s,mid-1,root); Init(st[root].son[1],mid+1,e,root); Updata(root); } void Rotate(int root,int dir) { st[st[root].pre].son[dir] = st[root].son[1^dir]; st[root].son[1^dir] = st[root].pre; if(st[st[st[root].pre].pre].son[0] == st[root].pre) st[st[st[root].pre].pre].son[0] = root; else st[st[st[root].pre].pre].son[1] = root; int temp = st[root].pre; st[root].pre = st[st[root].pre].pre; st[temp].pre = root; if(st[temp].son[dir] != -1) st[st[temp].son[dir]].pre = temp; Updata(temp); Updata(root); } int Splay(int root,int goal) { while(st[root].pre != goal) { Rotate(root,(st[st[root].pre].son[0] == root ? 0 : 1)); } return root; } int Search_Site(int root,int site) { //Push_Down(root); int temp; if(site <= st[root].ls || st[root].ls + st[root].sum < site) { if(st[root].ls + st[root].sum < site) temp = Search_Site(st[root].son[1],site - st[root].ls - st[root].sum); else temp = Search_Site(st[root].son[0],site); } else { temp = root; } //Updata(root); return temp; } bool cmp(NNum n1 , NNum n2) { return n1.num < n2.num; } int Del_Same(int n,NNum *TNum,NNum *Num) { sort(Num+1,Num+Top_Num,cmp); int i,j; TNum[1].num = Num[1].num; TNum[1].w = 1; for(i = 2,j = 1; i < n; ++i) { if(Num[i].num != TNum[j].num) { if(Num[i].num > TNum[j].num+1) { TNum[j+1].num = TNum[j].num+1; TNum[j+1].w = Num[i].num-TNum[j].num-1; ++j; } TNum[++j].num = Num[i].num; TNum[j].w = 1; } } return j; } void Link(int &root,int tr,int dir,int pre) { if(root == -1) { root = tr; st[tr].pre = pre; } else { Link(st[root].son[dir],tr,dir,root); } Updata(root); } int bs(int s,int e,int x) { int mid = (s+e)>>1; while(s < e) { if(Num[mid].num <= x && x < Num[mid].num + Num[mid].w) return Num[mid].site; if(x < Num[mid].num) e = mid-1; else s = mid+1; mid = (s+e)>>1; } return Num[s].site; } void Op_Top(int x,int &R) { R = Splay(bs(1,Top_Num,x),0); int TR = R; int tr = st[R].son[1]; R = st[R].son[0]; st[0].son[0] = R; st[R].pre = 0; st[TR].son[0] = -1,st[TR].son[1] = -1; st[TR].ls = 0,st[TR].rs = 0; st[TR].s = st[TR].sum; Link(R,tr,1,0); R = Splay(Search_Site(R,2),0); R = Splay(Search_Site(R,1),0); st[st[R].son[1]].son[0] = TR; st[TR].pre = st[R].son[1]; Updata(st[R].son[1]); Updata(R); } int Query(int x,int &R) { R = Splay(bs(1,Top_Num,x),0); return st[R].ls-st[R].data+x; } int Rank(int x,int &R) { R = Splay(Search_Site(R,x),0); return st[R].data+(x-st[R].ls-1); } int Judge(char order) { if(order == 'T') return 1; if(order == 'Q') return 2; if(order == 'R') return 3; } int main() { int T,icase = 1; int i,n,m; int root; char order[10]; scanf("%d",&T); while(T--) { scanf("%d %d",&n,&m); Top_Num = 1; for(i = 1; i <= m; ++i) { scanf("%s %d",order,&com[i].x); if(order[0] == 'T') TNum[Top_Num++].num = com[i].x; com[i].ty = Judge(order[0]); } TNum[Top_Num++].num = 0; TNum[Top_Num++].num = n+1; Top_Num = Del_Same(Top_Num,Num,TNum); root = -1,Top = 1; Init(root,1,Top_Num,0); st[0].son[0] = root,st[0].son[1] = -1; st[root].pre = 0; printf("Case %d:\n",icase++); for(i = 1; i <= m; ++i) { if(com[i].ty == 1) { Op_Top(com[i].x,root); } else if(com[i].ty == 2) { printf("%d\n",Query(com[i].x,root)); } else { printf("%d\n",Rank(com[i].x+1,root)); } } } return 0; }
HDU 3436 Queue-jumpers,布布扣,bubuko.com
原文:http://blog.csdn.net/u012161037/article/details/27707879