hdu3436Queue-jumpers(splay+离散化)
来源:互联网 发布:dcp1618w扫描软件 编辑:程序博客网 时间:2024/06/06 14:05
题目请戳这里
题目大意:有一个队,n个人,编号1-n,有3种操作:
top x:将编号x的人放到队列首;
query x:查询编号x的人现在排在第几位;
rank x:查询现在第x位的人编号;
题目分析:splay。人数编号是10^8级别的,但是操作不超过10^5个,只需将top操作中的编号离散化就可以了,因为剩下的人都是连续的,所以将剩下的连续的人缩成一个点,只记录起始位置的人和连续长度即可。
trick:n可以为1,这种情况下,任何操作都是无意义的,遇到查询操作就输出1。。这点TLE出翔了。。。
感想:splay非常强大,但是如果不能1y,那就意味着悲剧。。。
详情请见代码:
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N = 200005;typedef __int64 ll;int hash[N];int add[N];int index[N];int next[N];struct spt{ int l,r,f,val,size,len;}tree[N];int n,m,q;struct node{ char cmd; int x;}op[N];void init(){ for(int i = 0;i < N-10;i ++) next[i] = i + 1;}int newnode(int st,int ed){ int p = next[0]; next[0] = next[p]; tree[p].l = tree[p].r = tree[p].f = 0; tree[p].val = st; tree[p].size = tree[p].len = ed - st; return p;}void delnode(int p){ next[p] = next[0]; next[0] = p;}void del(int rt){ if(!rt) return; del(tree[rt].l); del(tree[rt].r); delnode(rt);}void pushup(int rt){ if(!rt) return; tree[rt].size = tree[tree[rt].l].size + tree[tree[rt].r].size + tree[rt].len;}void zig(int x){ int p = tree[x].f; tree[p].l = tree[x].r; if(tree[x].r) tree[tree[x].r].f = p; pushup(p); tree[x].r = p; tree[x].f = tree[p].f; pushup(x); tree[p].f = x; if(tree[x].f == 0) return; if(tree[tree[x].f].l == tree[x].r) tree[tree[x].f].l = x; else tree[tree[x].f].r = x;}void zag(int x){ int p = tree[x].f; tree[p].r = tree[x].l; if(tree[x].l) tree[tree[x].l].f = p; pushup(p); tree[x].l = p; tree[x].f = tree[p].f; pushup(x); tree[p].f = x; if(tree[x].f == 0) return; if(tree[tree[x].f].l == tree[x].l) tree[tree[x].f].l = x; else tree[tree[x].f].r = x;}int splay(int x,int goal){ while(tree[x].f != goal) { int p = tree[x].f; int g = tree[p].f; if(g == goal) { if(tree[p].l == x) zig(x); if(tree[p].r == x) zag(x); } else { if(tree[g].l == p && tree[p].l == x) zig(p),zig(x); else if(tree[g].l == p && tree[p].r == x) zag(x),zig(x); else if(tree[g].r == p && tree[p].l == x) zig(x),zag(x); else if(tree[g].r == p && tree[p].r == x) zag(p),zag(x); } } pushup(x); return x;}int build(int l,int r,int f){ if(l > r) return 0; int mid = (l + r)>>1; int p = newnode(hash[mid],hash[mid + 1]); tree[p].l = build(l,mid - 1,p); tree[p].f = f; tree[p].r = build(mid + 1,r,p); pushup(p); add[mid] = p; return p;}int getfront(int rt){ while(tree[rt].l) { rt = tree[rt].l; } return rt;}int getval(int pos,int rt){ if(!rt) return 0; if(pos <= tree[tree[rt].l].size) return getval(pos,tree[rt].l); if(pos <= tree[tree[rt].l].size + tree[rt].len) return rt;//pos - tree[tree[rt].l].size - 1 + tree[rt].val; return getval(pos - tree[tree[rt].l].size - tree[rt].len,tree[rt].r);}int Bin(int x){ int l,r,mid; l = 1;r = m; while(r >= l) { mid = (l + r)>>1; if(hash[mid] < x && hash[mid + 1] > x) return mid; if(hash[mid - 1] < x && hash[mid] > x) return mid - 1; if(hash[mid] == x) return mid; else if(hash[mid] > x) r = mid - 1; else l = mid + 1; }}void Top(int x,int &root){ int p = Bin(x); root = splay(add[p],0); if(tree[root].l == 0) { root = tree[root].r; tree[root].f = 0; } else if(tree[root].r == 0) { root = tree[root].l; tree[root].f = 0; } else {//后继旋到右子树,左子树挂到右子树,删除根 int nt = getfront(tree[root].r); tree[root].r = splay(nt,root); tree[tree[root].l].f = tree[root].r; tree[tree[root].r].l = tree[root].l; tree[tree[root].r].f = 0; root = tree[root].r; } pushup(root); int tmp = getfront(root); root = splay(tmp,0); tree[root].l = add[p]; tree[add[p]].f = root; tree[add[p]].l = tree[add[p]].r = 0; root = splay(add[p],0);}void Query(int x,int &root){ int p = Bin(x); root = splay(add[p],0); int ans = tree[tree[root].l].size + x - tree[root].val + 1; printf("%d\n",ans);}void Rank(int x,int &root){ int p = getval(x,root); root = splay(p,0); printf("%d\n",x - tree[tree[root].l].size - 1 + tree[root].val);}int main(){ int _,i,j; int cas = 0; char ss[10]; int root; init(); scanf("%d",&_); while(_--) { scanf("%d%d",&n,&q); printf("n:%d q:%d\n",n,q); j = 1; printf("Case %d:\n",++cas); if(n == 1) { for(i = 1;i <= q;i ++) { scanf("%s%d",ss,&j); if(*ss == 'R' || *ss == 'Q') printf("1\n"); } continue; } for(i = 1;i <= q;i ++) { scanf("%s",ss); op[i].cmd = *ss; scanf("%d",&op[i].x); if(*ss == 'T') { hash[j] = op[i].x; j ++; } } sort(hash + 1,hash + j); m = 2; for(i = 2;i < j;i ++) if(hash[i] != hash[i - 1]) hash[m ++] = hash[i]; for(i = 2,j = m;i < j;i ++) if(hash[i] != hash[i - 1] + 1) hash[m ++] = hash[i - 1] + 1; if(hash[j - 1] < n) hash[m ++] = hash[j - 1] + 1; hash[m ++] = n + 1; if(hash[1] != 1) hash[m ++] = 1; sort(hash + 1,hash + m); m --; root = build(1,m - 1,0); for(i = 1;i <= q;i ++) { switch(op[i].cmd) { case 'T':Top(op[i].x,root);break; case 'Q':Query(op[i].x,root);break; case 'R':Rank(op[i].x,root);break; } } del(root); } return 0;}//140MS4356K
- hdu3436Queue-jumpers(splay+离散化)
- 【Splay】【离散化】hdu3436 Queue-jumpers
- HDU 3436 Queue-jumpers Splay+离散化
- Splay树 + 离散化 —— HDU 3436 Queue-jumpers
- HDU 3436 Queue-jumpers splay 离散化 模拟
- HDU 3436 Queue-jumpers(SplayTree+离散化)
- HDU3436[离散化splay]
- hdu3436 Queue-jumpers(Splay)
- 【BZOJ2827】千山鸟飞绝 离散化+splay
- hdu 3436 Queue-jumpers(Splay)
- 【splay tree】 HDOJ Queue-jumpers
- 【HDU3436】 Queue-jumpers (Splay tree)
- HDU 3436 Queue-jumpers(Splay)
- HDU 3436 Queue-jumpers splay
- hdu 3436 splay树+离散化*
- HDU 3436 Queue-jumpers (Splay tree)
- HDU 3436 Queue-jumpers(splay tree)
- hdu 3436 Queue-jumpers(splay tree)
- 播放简单音效
- 拖延心理学
- isolation_level
- xtrabackup-2.1.2-611安装
- 参考博客的网址总结(一)
- hdu3436Queue-jumpers(splay+离散化)
- 翻译:Serial Communications in Win32
- JSON_org.apache.commons.lang.exception.NestableRuntimeException
- HTML Frame 居中 上下分三层 中间分两层
- ofbiz12.04环境搭建
- 功能强大的编辑器——Vi
- 针对webview的开发
- 2013年小米校园招聘笔试题---研发
- python获取新浪微博授权