hdu 3436
2014-09-09 19:14
176 查看
一开始,直接无脑的对n数组维护。打完之后一看n的范围,默默的删了。
一看范围,就知道要先读进来询问,把涉及到的x做一个统计,这样n的数组
1,2,...,n
(1,x0-1),x0,(x0+1,x1),x1,...,n
这样子就缩好了(一个节点是一个区间)。记录每个节点的起始数。
统计的信息,区间和(即数的个数)。
这样三个操作都能写啦。
View Code
一看范围,就知道要先读进来询问,把涉及到的x做一个统计,这样n的数组
1,2,...,n
(1,x0-1),x0,(x0+1,x1),x1,...,n
这样子就缩好了(一个节点是一个区间)。记录每个节点的起始数。
统计的信息,区间和(即数的个数)。
这样三个操作都能写啦。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #define KT ch[ch[root][1]][0] #define LC ch[x][0] #define RC ch[x][1] #define N 310001 using namespace std; struct node{ char op[10]; int x; void in(){ scanf("%s%d",op,&x); } }; struct SplayTree{ int root; int fa ; int ch [2]; int sz ; int top1; int top2; int ss ; int que ; void pushdown(int x){ } void pushup(int x){ sz[x]=1+sz[LC]+sz[RC]; sum[x]=val[x]+sum[LC]+sum[RC]; } void rotate(int x,bool f){ int y=fa[x]; int z=fa[y]; pushdown(y); pushdown(x); ch[y][!f]=ch[x][f]; fa[ch[x][f]]=y; fa[x]=z; if (z) { ch[z][ch[z][1]==y] = x; } ch[x][f] = y; fa[y]=x; pushup(y); } void splay(int x, int g) { int y = fa[x]; pushdown(x); while(y!=g){ int z= fa[y]; bool f = (ch[y][0]==x); if(z != g && f == (ch[z][0]==y)){ rotate(y,f); } rotate(x,f); y=fa[x]; } pushup(x); if(g==0) root = x; } void rotateTo(int k,int g) { int x=root; pushdown(x); while(sz[LC] != k){ if(k<sz[LC]){ x=LC; }else{ k -= sz[LC] + 1; x = RC; } pushdown(x); } splay(x,g); } void build(int l,int r,int f){ if(l>r){ return ; } int x = (l + r) >> 1; LC = (x - 1 >= l)? (x - 1 + l)>> 1 :0; RC = (r >= x + 1)? (x + 1 + r)>> 1 :0; fa[x] = f; build(l,x - 1,x); build(x + 1,r,x); pushup(x); } void erase(int x){ if(x==0) return; int father= fa[x]; int head = 0, tail=0; for(que[tail++] =x ; head < tail; head++){ ss[top2++] = que[head]; if(ch[que[head]][0]){ que[tail++]=ch[que[head]][0]; } if(ch[que[head]][1]){ que[tail++] = ch[que[head]][1]; } } ch[father][ch[father][1]==x]=0; pushup(father); } void treaval(int x){ if (x) { pushdown(x); treaval(LC); printf("@%d",val[x]); //ans[cnt++]=val[x]; treaval(RC); } } void newNode(int &x,int c,int r,int st){ if(top2){ x = ss[--top2]; } else { x = ++top1; } LC = RC = fa[x] =0; sz[x] = 1; val[x] = c; ret[x] = r; start[x]=st; if(r&&pos.find(r)==pos.end()){ pos[r]=x; } } void makeTree(int &x, int l, int r, int f){ if(l > r){ return; } int m=(l+r)>>1; newNode(x, num[m], m%2?a[m/2]:0,b[m]); makeTree(LC,l,m-1,x); makeTree(RC,m+1,r,x); fa[x]=f; pushup(x); } void debug(){ treaval(root); cout<<endl; } void cutTo(int l,int r,int c){ rotateTo(l-1,0); rotateTo(r+1,root); //debug(); int tmp=KT; KT=0; pushup(ch[root][1]); pushup(root); rotateTo(c,0); rotateTo(c+1,root); fa[tmp]=ch[root][1]; KT=tmp; pushup(ch[root][1]); pushup(root); //debug(); } int find(int x,int k){ if(sum[LC]<=k-1&&sum[LC]+val[x]>=k){ return start[x]+k-sum[LC]-1; } else if(sum[LC]>=k){ return find(LC,k); }else { return find(RC,k-sum[LC]-val[x]); } } void init(int n,int m){ pos.clear(); top1=top2=root=0; newNode(root,0,0,0); newNode(ch[root][1],0,0,0); fa[ch[root][1]]=root; for(int i=0;i<m;i++) { Q[i].in(); aa[i]=Q[i].x; } sort(aa,aa+m); a[0]=aa[0]; int cnt=1; for(int i=1;i<m;i++){ if(aa[i]!=aa[i-1]) a[cnt++]=aa[i]; } m=cnt; num[0]=a[0]-1; b[0]=1; for(int i=0;i<m;i++){ if(i!=0){ num[i*2]=a[i]-a[i-1]-1; b[i*2]=a[i-1]+1; } num[i*2+1]=1; b[i*2+1]=a[i]; } num[m*2]=n-a[m-1]; b[m*2]=a[m-1]+1; makeTree(KT,0,2*m,ch[root][1]); pushup(ch[root][1]); pushup(root); } void top(int v){ int x=pos[v]; splay(x,0); int k=sz[ch[root][0]]; cutTo(k,k,0); } int rank(int k){ return find(root,k); } int query(int v){ int x=pos[v]; splay(x,0); //debug(); return sum[LC]+1; } void solve(int m){ int v; for(int i=0;i<m;i++){ // debug(); v=Q[i].x; if(Q[i].op[0]=='T'){ top(v); }else if(Q[i].op[0]=='R'){ printf("%d\n",rank(v)); }else{ printf("%d\n",query(v)); } } } int val ;//数值 int sum ; int ret ;//结果 int start ;//该区间开始的数; int aa ; int a ; int b ; int num ; //int pos ; map<int,int>pos; node Q ; }spt; int main() { int T; cin>>T; int n,m; int cas=1; while(T--){ scanf("%d%d",&n,&m); printf("Case %d:\n",cas++); spt.init(n,m); spt.solve(m); } return 0; }
View Code
相关文章推荐
- hdu 3436 线段树 一顿操作
- hdu 3436 线段树 一顿操作
- HDU 3436 Queue-jumpers Splay
- HDU 3436 Queue-jumpers(Splay)
- HDU 3436 Queue-jumpers
- HDU 3436 Queue-jumpers
- hdu 3436 Queue-jumpers
- Hdu 3436 Queue-jumpers(把第x个人放到队伍的前面,查询第x个人的位置,查询第x个位置是哪个人)
- HDU 3436 Queue-jumpers(SplayTree+离散化)
- HDU-3436 Queue-jumpers(Splay树)
- hdu 3436 Queue-jumpers(Splay)
- hdu 3436 Queue-jumpers 树状数组求第k大数 (不断将数调到第一个位置)
- HDU 3436 Queue-jumpers (Splaytree)
- hdu 3436 Queue-jumpers (经典离散化,树状数组实现lower_bound)
- HDU 3436 Queue-jumpers
- HDU 3436 splay
- hdu 3436 Queue-jumpers(Splay Tree)
- HDU 3436 Queue-jumpers splay 离散化 模拟
- HDU 3436--Queue-jumpers (树状数组 or Splay Tree)
- HDU 3436:splay tree