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 ...
随机推荐
- 夺命雷公狗---linux之红帽的安装
夺命雷公狗分享的第二套安装linux方法是RadHad的安装方法,,, 点击然后就自动重启了
- 我的代码观——关于ACM编程风格与librazy网友的对话
序 在拙文 <高手看了,感觉惨不忍睹——关于“[ACM]杭电ACM题一直WA求高手看看代码”>中,我对ACMer们的一些代码“惯例”发表了我的看法, librazy网友在评论中给出了他的一 ...
- 使用UEFI BIOS Updater(UBU)来更新CPU微代码
原文地址:http://www.win-raid.com/t154f16-Tool-Guide-News-quot-UEFI-BIOS-Updater-quot-UBU.html 链接: http:/ ...
- ADO.NET中的TransactionScope何时需要启用MSTDC(分布式事务管理)
我们知道在ADO.NET中可以用TransactionScope来将多个SqlConnection(多个数据库连接)执行的Sql语句放入一个事物中提交或取消,但是使用TransactionScope的 ...
- Spring之AOP面向切片
一.理论基础: AOP(Aspectoriented programming)面向切片/服务的编程,在Spring中使用最多的是对事物的处理.而AOP这种思想在程序中很多地方可以使用的,比如说, ...
- 如何在视频处理控件TVideoGrabber中设置音频捕捉设备
TVideoGrabber不仅可以捕捉视频,还可以作为多媒体播放器,并支持包括C#..NET.VB.NET.C++.Delphi.C++Builder和ActiveX平台,本文将剖析TVideoGra ...
- tp框架支付宝手机网页支付
开发环境:linux+php+mysql 密钥生成: 1.genrsa -out rsa_private_key.pem 1024 生成商户私钥,因在php环境,一定要保持原始状态,不得修改.rsa_ ...
- 深入理解HTTP协议、HTTP协议原理分析【转】
转自:http://blog.csdn.net/lmh12506/article/details/7794512 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 基础概念篇 ...
- js对select动态添加和删除OPTION
<select id="ddlResourceType" onchange="getvalue(this)"> </select> 动态 ...
- php 的 构造函数 和 析构函数
构造函数 在C++ java里的应用及其普遍,今天好好研究了一下 php 的 构造函数 和 析构函数 构造函数 和 析构函数 构造函数 void __construct ([ mixed $args ...