Splay(hdu4441Queue Sequence)好题
来源:互联网 发布:校园网络建设招标书 编辑:程序博客网 时间:2024/06/11 02:48
Queue Sequence
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1412 Accepted Submission(s): 356
Problem Description
There's a queue obeying the first in first out rule. Each time you can either push a number into the queue (+i), or pop a number out from the queue (-i). After a series of operation, you get a sequence (e.g. +1 -1 +2 +4 -2 -4). We call this sequence a queue sequence.
Now you are given a queue sequence and asked to perform several operations:
1. insert p
First you should find the smallest positive number (e.g. i) that does not appear in the current queue sequence, then you are asked to insert the +i at position p (position starts from 0). For -i, insert it into the right most position that result in a valid queue sequence (i.e. when encountered with element -x, the front of the queue should be exactly x).
For example, (+1 -1 +3 +4 -3 -4) would become (+1 +2 -1 +3 +4 -2 -3 -4) after operation 'insert 1'.
2. remove i
Remove +i and -i from the sequence.
For example, (+1 +2 -1 +3 +4 -2 -3 -4) would become (+1 +2 -1 +4 -2 -4) after operation 'remove 3'.
3. query i
Output the sum of elements between +i and -i. For example, the result of query 1, query 2, query 4 in sequence (+1 +2 -1 +4 -2 -4) is 2, 3(obtained by -1 + 4), -2 correspond.
Now you are given a queue sequence and asked to perform several operations:
1. insert p
First you should find the smallest positive number (e.g. i) that does not appear in the current queue sequence, then you are asked to insert the +i at position p (position starts from 0). For -i, insert it into the right most position that result in a valid queue sequence (i.e. when encountered with element -x, the front of the queue should be exactly x).
For example, (+1 -1 +3 +4 -3 -4) would become (+1 +2 -1 +3 +4 -2 -3 -4) after operation 'insert 1'.
2. remove i
Remove +i and -i from the sequence.
For example, (+1 +2 -1 +3 +4 -2 -3 -4) would become (+1 +2 -1 +4 -2 -4) after operation 'remove 3'.
3. query i
Output the sum of elements between +i and -i. For example, the result of query 1, query 2, query 4 in sequence (+1 +2 -1 +4 -2 -4) is 2, 3(obtained by -1 + 4), -2 correspond.
Input
There are less than 25 test cases. Each case begins with a number indicating the number of operations n (1 ≤ n ≤ 100000). The following n lines with be 'insert p', 'remove i' or 'query i'(0 ≤ p ≤ length (current sequence), 1 ≤ i, i is granted to be in the sequence).
In each case, the sequence is empty initially.
The input is terminated by EOF.
In each case, the sequence is empty initially.
The input is terminated by EOF.
Output
Before each case, print a line "Case #d:" indicating the id of the test case.
After each operation, output the sum of elements between +i and -i.
After each operation, output the sum of elements between +i and -i.
Sample Input
10insert 0insert 1query 1query 2insert 2query 2remove 1remove 2insert 2query 36insert 0insert 0remove 2query 1insert 1query 2
Sample Output
Case #1:2-120Case #2:0-1
Source
题目支持三种操作:
insert pos, 把x(x为可用的最小的数)插入对应位置,-x插入对应位置,如1 2 -1 -2 ,3要插入2后面,-3插入-2后面,而求尽量靠右
remove x,把x,-x移除
query x询问x与-x之间的数的和
position数组保存x对应的伸展树中的编号,线段树维护最小的可用的数
insert操作插入x的时候比较好操作,-x的时候,因为要保持顺序,所以x前面有多少个正数,-x前面就有多少个负数,又因为尽力量靠右,所以也就是第n+1个负数的左边
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;#define Key_value ch[ch[root][1]][0]const int maxn=200010;const int INF=1000000000;typedef long long LL;int M;int ch[maxn][2],size[maxn],pre[maxn],cnt[maxn][2],key[maxn];LL sum[maxn];int position[maxn][2];int root,tot1,tot2;set<int> sp;void NewNode(int &r,int f,int val){ r=++tot1; ch[r][0]=ch[r][1]=0; cnt[r][0]=val>0; cnt[r][1]=val<0; sum[r]=val; pre[r]=f; size[r]=1; key[r]=val;}void pushup(int r){ if(!r)return; int lson=ch[r][0],rson=ch[r][1]; size[r]=size[lson]+size[rson]+1; sum[r]=sum[lson]+sum[rson]+key[r]; cnt[r][0]=cnt[lson][0]+cnt[rson][0]+(key[r]>0); cnt[r][1]=cnt[lson][1]+cnt[rson][1]+(key[r]<0);}void init(){ root=tot1=tot2=0; ch[root][0]=ch[root][1]=pre[root]=cnt[root][0]=cnt[root][1]=key[root]=size[root]=0; NewNode(root,0,0); NewNode(ch[root][1],root,0); pushup(ch[root][1]); pushup(root); // cout<<size[root]<<"***"<<endl;}void Rotate(int x,int kind){ int y=pre[x]; ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y]; ch[x][kind]=y; pre[y]=x; pushup(y);}void Splay(int r,int goal){ while(pre[r]!=goal) { if(pre[pre[r]]==goal) { Rotate(r,ch[pre[r]][0]==r); } else { int y=pre[r]; int kind=(ch[pre[y]][0]==y); if(ch[y][kind]==r) { Rotate(r,!kind); Rotate(r,kind); } else { Rotate(y,kind); Rotate(r,kind); } } } pushup(r); if(goal==0)root=r;}int get_kth(int r,int k){ int t=size[ch[r][0]]+1; if(t==k)return r; if(t>k)return get_kth(ch[r][0],k); return get_kth(ch[r][1],k-t);}int find(int r,int k){ int lson=ch[r][0],rson=ch[r][1]; if(cnt[lson][1]==k&&key[r]<0) { Splay(r,0); return size[ch[root][0]]; } else if(cnt[lson][1]>=k+1)return find(lson,k); else return find(rson,k-cnt[lson][1]-(key[r]<0));}struct InterValTree{ int minv[maxn<<2]; void build(int o,int l,int r) { minv[o]=0; if(l==r) { minv[o]=l; return; } int mid=(l+r)>>1; build(o<<1,l,mid); build(o<<1|1,mid+1,r); push_up(o); } void push_up(int o) { minv[o]=min(minv[o<<1],minv[o<<1|1]); } void update(int o,int l,int r,int pos,int flag) { if(l==r) { if(flag)minv[o]=INF; else minv[o]=l; return; } int mid=(l+r)>>1; if(pos<=mid)update(o<<1,l,mid,pos,flag); else update(o<<1|1,mid+1,r,pos,flag); push_up(o); }}tree;void debug(int r){ if(!r)return; debug(ch[r][0]); printf("%d ",key[r]); debug(ch[r][1]);}void Insert(int pos){ int num=tree.minv[1]; tree.update(1,1,M,num,1); Splay(get_kth(root,pos+1),0); Splay(get_kth(root,pos+2),root); NewNode(Key_value,ch[root][1],num); position[num][0]=Key_value; pushup(ch[root][1]); pushup(root); Splay(Key_value,0); int n=cnt[ch[root][0]][0]; if(cnt[root][1]<=n) { int m=size[root]-2+1; Splay(get_kth(root,m),0); Splay(get_kth(root,m+1),root); NewNode(Key_value,ch[root][1],-num); position[num][1]=Key_value; } else { int m=find(root,n); Splay(get_kth(root,m),0); Splay(get_kth(root,m+1),root); NewNode(Key_value,ch[root][1],-num); position[num][1]=Key_value; } pushup(ch[root][1]); pushup(root);}void Delete(int x){ Splay(x,0); int pos=size[ch[x][0]]; Splay(get_kth(root,pos),0); Splay(get_kth(root,pos+2),root); pre[Key_value]=0; Key_value=0; pushup(ch[root][1]); pushup(root);}void Remove(int x){ Delete(position[x][0]); Delete(position[x][1]); tree.update(1,1,M,x,0);}void Query(int x){ Splay(position[x][0],0); Splay(position[x][1],position[x][0]); cout<<sum[Key_value]<<endl;;}int main(){ char op[10]; int cas=1; while(scanf("%d",&M)!=EOF) { tree.build(1,1,M); init(); printf("Case #%d:\n",cas++); for(int i=1;i<=M;i++) { int x; scanf("%s%d",op,&x); if(op[0]=='i')Insert(x); else if(op[0]=='r')Remove(x); else if(op[0]=='q')Query(x); } } return 0;}
0 0
- Splay(hdu4441Queue Sequence)好题
- hdu 4441 Queue Sequence(线段树&splay数据结构的好题!)
- Splay(sequence)
- Sequence by 唐迪(不是splay)
- 【NOI2005 Sequence】序列之神Splay和Splay“基础题”Sequence
- spoj 1470——Another Sequence Problem(Splay Tree)
- HDU-3487 Play with Chain (splay好题 带翻转 cut-link操作)
- E. LIS of Sequence(好题 LIS )
- hdu Beauty of Sequence (好题_集合问题)
- hdoj Arithmetic Sequence 5400 (构造等差数列+技巧) 好题
- 【HDU 4441】 Queue Sequence(Splay)
- HDU 4441 【Splay】 Queue Sequence
- 【HDU 4441】 Queue Sequence 【Splay】
- HDU 2062 Subset sequence 【好题】
- poj 3581 Sequence (后缀数组好题)
- HDU 4441 Queue Sequence(12年天津现场,Splay+线段树)
- HDU 4441 Queue Sequence[Splay Tree]
- hdu4441 Queue Sequence(线段树+splay)
- js prototype call 函数的讲解
- 将博客搬至CSDN
- 代码清单20:DefaultActionInvocation.createAction()方法
- [codevs 1302] 小矮人(2002年CEOI中欧信息学奥赛)
- 关于滚回csdn
- Splay(hdu4441Queue Sequence)好题
- 【java编程】反射之更改成员变量
- UILabel字体加粗等属性和特效
- 一个简单的groovy script生成的class文件及其反编译
- hdu5171 GTY's birthday gift(BestCoder Round #29 1002)
- Net总结
- 优化AJAX提交到Handler的ProcessRequest方法
- 每天一点数据库之-----Day 3 数据的增改删
- 记录一些有用的网站