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 ...
随机推荐
- ssh-copy-id帮你建立信任
一.ssh-keygen -t rsa [nameA@machineA]$ ssh-keygen -t rsa Generating public/private rsa key pair. Ente ...
- PAT乙级 1007. 素数对猜想 (20)
1007. 素数对猜想 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 让我们定义 dn 为:dn = ...
- ImagXpress中如何修改Alpha通道方法汇总
ImagXpress支持处理Alpha通道信息来管理图像的透明度,Alpha通道支持PNG ,TARGA和TIFF文件,同时还支持BMP和ICO文件.如果说保存的图像样式不支持Alpha通道,就将会丢 ...
- 10 个迅速提升你 Git 水平的提示【转】
转自:https://www.oschina.net/translate/10-tips-git-next-level 最近我们推出了两个教程:熟悉Git的基本功能和让你在开发团队中熟练的使用Git ...
- JVM学习笔记(一)------基本结构【转】
转自:http://blog.csdn.net/cutesource/article/details/5904501 版权声明:本文为博主原创文章,未经博主允许不得转载. 从Java平台的逻辑结构上来 ...
- Java程序编译和运行的过程【转】
转自:http://www.360doc.com/content/14/0218/23/9440338_353675002.shtml Java整个编译以及运行的过程相当繁琐,本文通过一个简单的程序来 ...
- Entrust是一种为Laravel5添加基于角色的权限的简洁而灵活的方法。
安装 首先要在composer.json中添加: "zizaco/entrust": "5.2.x-dev" 然后运行composer install 或者 c ...
- 将helps.php或者functions.php直接进行了加载
TP3系列中functions.php文件默认其实是空文件,很好找.我们可以直接封装代码. Laravel5系列中的path/vendor/laravel/framework/src/Illumina ...
- 探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法
前言相信这样一个问题,大家都不会陌生,“有什么的方法可以使Android的程序APK不用安装,而能够直接启动”.发现最后的结局都是不能实现这个美好的愿望,而腾讯Android手机游戏平台却又能实现这个 ...
- HDU 5794:A Simple Chess(Lucas + DP)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5794 题意:让一个棋子从(1,1)走到(n,m),要求像马一样走日字型并只能往右下角走.里 ...