HDU 4441 Queue Sequence(splay)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4441
题意:一个数列,三种操作:(1)插入:找到没在当前数列中的最小的正整数i,将其插在位置p之后,并将-i插入某个位置使得满足先进先出(i表示进,-i表示出),这个位置尽量靠右;(2)删除:删掉数字i以及-i;(3)询问:查询i和-i之间的数字的和。
思路:对于没在数列中的数字可以用一个set直接维护。i的插入是正常的splay操作。对于-i的插入,我们首先找到i之前有几个正数,比如有x个,那么-i必然是插在第x+1个负数的前面,因此在splay节点中要保存负数的个数。删除和查询都是splay正常操作。
struct node { i64 sum; int val; int size[2]; int Size; node *c[2],*p; }; node a[N],*root,*nullNode; int cnt; void pushUp(node *p) { if(p==nullNode) return; p->Size=1; p->sum=p->val; p->size[0]=p->size[1]=0; if(p->val>0) p->size[1]++; else if(p->val<0) p->size[0]++; if(p->c[0]!=nullNode) { p->Size+=p->c[0]->Size; p->sum+=p->c[0]->sum; p->size[0]+=p->c[0]->size[0]; p->size[1]+=p->c[0]->size[1]; } if(p->c[1]!=nullNode) { p->Size+=p->c[1]->Size; p->sum+=p->c[1]->sum; p->size[0]+=p->c[1]->size[0]; p->size[1]+=p->c[1]->size[1]; } } int ok(node *p) { return p!=nullNode&&(p!=&a[1])&&(p!=&a[2]); } node *newNode(int val,node *p) { node *e=&a[val>0?val:-val+100000]; e->c[0]=e->c[1]=nullNode; e->p=p; e->Size=1; e->val=e->sum=val; e->size[0]=e->size[1]=0; if(val>0) e->size[1]++; else e->size[0]++; return e; } void init() { nullNode=new node(); nullNode->size[0]=nullNode->size[1]=0; nullNode->Size=0; nullNode->sum=0; nullNode->c[0]=nullNode->c[1]=nullNode->p=nullNode; root=new node(); root->c[0]=root->c[1]=root->p=nullNode; root->sum=0; root->val=0; root->size[0]=root->size[1]=0; root->Size=1; root->c[1]=new node(); root->c[1]->c[0]=root->c[1]->c[1]=nullNode; root->c[1]->p=root; root->c[1]->sum=root->c[1]->val=-1; root->c[1]->Size=1; root->c[1]->size[0]=root->c[1]->size[1]=0; root->c[1]->size[0]++; pushUp(root); } void zig(node *x) { node *p=x->p,*q=p->p; p->c[0]=x->c[1]; if(x->c[1]!=nullNode) x->c[1]->p=p; x->c[1]=p; p->p=x; x->p=q; if(q!=nullNode) { if(q->c[0]==p) q->c[0]=x; else q->c[1]=x; } pushUp(p); pushUp(x); if(root==p) root=x; } void zag(node *x) { node *p=x->p,*q=p->p; p->c[1]=x->c[0]; if(x->c[0]!=nullNode) x->c[0]->p=p; x->c[0]=p; p->p=x; x->p=q; if(q!=nullNode) { if(q->c[0]==p) q->c[0]=x; else q->c[1]=x; } pushUp(p); pushUp(x); if(root==p) root=x; } void splay(node *x,node *goal) { while(x->p!=goal) { if(x->p->p!=goal) { if(x->p->p->c[0]==x->p) { if(x->p->c[0]==x) zig(x->p),zig(x); else zag(x),zig(x); } else { if(x->p->c[1]==x) zag(x->p),zag(x); else zig(x),zag(x); } } else { if(x->p->c[0]==x) zig(x); else zag(x); } } } void select(int k,node *goal) { node *p=root; while(k!=p->c[0]->Size+1) { if(k<=p->c[0]->Size) p=p->c[0]; else { k-=1+p->c[0]->Size; p=p->c[1]; } } splay(p,goal); } int curNodeNum; void insert(int p,int val) { select(p,nullNode); select(p+1,root); node *e=newNode(val,root->c[1]); root->c[1]->c[0]=e; splay(e,nullNode); curNodeNum++; } node *getPre(node *u) { splay(u,nullNode); u=u->c[0]; while(u->c[1]!=nullNode) u=u->c[1]; return u; } node *getNext(node *u) { splay(u,nullNode); u=u->c[1]; while(u->c[0]!=nullNode) u=u->c[0]; return u; } node *getKth0(int k) { node *p=root; while(1) { if(p->c[0]->size[0]>=k) p=p->c[0]; else if(p->c[0]->size[0]+1==k) { if(p->val<0) return p; k-=p->c[0]->size[0]; p=p->c[1]; } else { k-=p->c[0]->size[0]; if(p->val<0) k--; p=p->c[1]; } } } void del(node *p) { node *u=getPre(p); node *v=getNext(p); splay(u,nullNode); splay(v,root); root->c[1]->c[0]=nullNode; splay(root->c[1],nullNode); curNodeNum--; } set<int> S; int n; void deal() { S.clear(); init(); curNodeNum=2; int i; for(i=1;i<=100000;i++) S.insert(i); while(n--) { char op[10]; int p; scanf("%s%d",op,&p); if(op[0]=='i') { int t=*S.begin(); S.erase(t); insert(p+1,t); splay(a+t,nullNode); int num=0; if(root->c[0]!=nullNode) num+=root->c[0]->size[1]; if(root->val>0) num++; node *u=getKth0(num); node *v=getPre(u); splay(v,nullNode); splay(u,root); node *tmp=newNode(-t,root->c[1]); root->c[1]->c[0]=tmp; splay(tmp,nullNode); curNodeNum++; } else if(op[0]=='r') { S.insert(p); del(a+p); del(a+p+100000); } else { node *u=a+p; node *v=a+p+100000; splay(u,nullNode); splay(v,root); i64 sum=root->c[1]->c[0]->sum; output(sum); puts(""); } } } int main() { int num=0; while(scanf("%d",&n)!=-1) { printf("Case #%d:\n",++num); deal(); } }
HDU 4441 Queue Sequence(splay)的更多相关文章
- HDU 4441 Queue Sequence(优先队列+Treap树)(2012 Asia Tianjin Regional Contest)
Problem Description There's a queue obeying the first in first out rule. Each time you can either pu ...
- HDU 1711 Number Sequence(数列)
HDU 1711 Number Sequence(数列) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- HDU 1005 Number Sequence(数列)
HDU 1005 Number Sequence(数列) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav ...
- hdu 4915 Parenthese sequence(模拟)2014多培训学校5现场
Parenthese sequence Time Limit: ...
- hdu 6047 Maximum Sequence(贪心)
Description Steph is extremely obsessed with "sequence problems" that are usually seen on ...
- HDU 4441 Queue Sequence
http://acm.hdu.edu.cn/showproblem.php?pid=4441 题意:对于一个序列,每次有三种操作 insert pos 表示在pos插入一个数,这个数是最小的正数 ...
- HDU 1711 Number Sequence(KMP)附带KMP的详解
题目代号:HDU 1711 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Number Sequence Time Limit: 10000/ ...
- hdu 6299 Balanced Sequence (贪心)
Balanced Sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 1890 Robotic Sort(splay)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=1890 [题意] 给定一个序列,每次将i..P[i]反转,然后输出P[i],P[i]定义为当前数字i ...
随机推荐
- User Managerment 职责不能使用的问题
1.此职责默认的是没有启用授权的(grant),需要在系统管理员职责下搜索到对应的菜单,进行grant 2.就算授权后,用户还是不能进行操作,需要进行以下设置: 1. Log into the app ...
- 夺命雷公狗---Thinkphp----6之管理员的增删改查之-未验证
首先我们创建多一个控制器UserController.class.php,主要用于管理员的增删改查操作: 代码如下所示: <?php namespace Admin\Controller; us ...
- React+Node.js+Express+mongoskin+MongoDB
首发:个人博客,更新&纠错&回复 采用React + Node.js + Express + mongoskin + MongoDB技术开发的一个示例,演示地址在这里,项目源码在这里. ...
- 启用 TStringGrid 的自画功能,并避免重影
FMX 控件的 TStringGrid 下,有时为了让不同行或不同 Cell 的显示颜色.字体等有各种不同的颜色, 必须采用自画, 即在其 OnDrawColumnCell 事件中写自己的控制代码显示 ...
- 【python cookbook】【字符串与文本】11.从字符串中去掉不需要的字符
问题:在字符串的开始.结尾或中间去掉不需要的字符,比如说空格符 解决方案: 1.字符串开始或结尾处去掉字符:str.strip() 2.从左或从右侧开始执行去除字符:str.lstrip().str. ...
- The C++ Standard Library --- A Tutorial Reference 读书笔记
5.2 Smart Pointer(智能指针) shared_ptr的aliasing构造函数,接受一个shared pointer和一个raw pointer.它允许你掌握一个事实:某对象拥有另一个 ...
- 网络统计学与web前端开发基础技术
网络统计学与web前端开发基础技术 学习web前端开发基础技术(网页设计)需要了解:HTML.CSS.JavaScript三种语言.下面我们就来了解一下这三门技术在网页设计中的用途: HTML是网页内 ...
- [ios][swift]提示框,并自动消失
参考: 提示框:http://blog.csdn.net/gishero/article/details/43941361 提示框自动消失:http://www.cnblogs.com/yemingl ...
- raw_input() 与 input()
这两个均是 python 的内建函数,通过读取控制台的输入与用户实现交互.但他们的功能不尽相同. >>> raw_input_A = raw_input("raw_inpu ...
- 单利 复利计算器程序1.0 2.0 3.0 [ 合 ] 之 C语言
本程序用C语言编写~~~ 1.计算:本金为100万,利率或者投资回报率为3%,投资年限为30年,那么,30年后所获得的利息收入:按复利计算公式来计算就是:1,000,000×(1+3%)^30 1 v ...