HDU 4967(Handling the Past-线段树维护可持久化栈操作)
2015-09-06 16:52
459 查看
Handling the Past
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 450 Accepted Submission(s): 188
[align=left]Problem Description[/align]
Nowadays, cloud computing is a popular topic among business and technology circles. In cloud computing, everything can be stored in a cloud server, and clients deal with the data by sending operation-requests to the server. However,
such client-server mode may cause some problems. For example, if you send two operations op1 and op2 to the server, expecting that op1 should be executed first and followed by op2. Due to the network delay, op1 may arrive at the server later than op2. In order
to inform the server the correct operation order, each operation is associated with a timestamp. Now if the server gets two operations (op1, t1) and (op2, t2), where t1 < t2, the server will know that op1 should be executed earlier than op2. So, if (op2, t2)
arrives first, the server will execute op2 immediately. And when (op1, t1) arrives, the server will find that op1 should be executed before op2 (because t1 < t2), thus it has to undo op2, execute op1, and re-execute op2 finally.
In this problem, you are asked to simulate the above process. To simplify the problem, we assume that there is only a stack, a last-in-first-out data structure as you know, stored in the server. Three types of operations are considered, whose formats and semantics
are given as follows.
push x t -- push x into the stack, and t is a timestamp
pop t -- pop the top element from the stack, and t is a timestamp
peak t -- return the top element in the stack, and t is a timestamp
When an operation op with a timestamp t arrives, the server process it in the following three steps:
Step 1: undo all the "push" and "pop" operations having timestamp larger than t.
Step 2: execute op.
Step 3: redo all the "push" and "pop" operations which were undone in step 1.
The server do not need to undo or redo any "peak" operations. In another word, every "peak" operation is executed only once after it arrives at the server.
Given the operations arriving at the server in order, you are asked to simulate the above process. The stack is empty initially. To simplify the problem further, another two assumptions are made:
1. All the "pop" operations are valid. In another word, if you simulate the process correctly, no "pop" operations will be performed on an empty stack.
2. All timestamps are different.
[align=left]Input[/align]
The input contains multiple test cases.
Each case begins with an integer N (1<=N<=50000), indicating the number of operations. The following N lines each contain an operation in one of the following three formats:
push x t
pop t
peak t
where 0<=x, t<=10^9.
The operations are given in the order in which they arrive at the server.
The input is terminated by N = 0.
[align=left]Output[/align]
For each case, output "Case #X:" in a line where X is the case number, staring from 1. Then for each "peak" operation, output the answer in a line. If the stack is empty, output -1 instead.
[align=left]Sample Input[/align]
7 push 100 3 push 200 7 peak 4 push 50 2 pop 5 peak 6 peak 8 4 push 25 1 pop 5 peak 6 peak 3 4 push 10 1 peak 7 pop 3 peak 4 0
[align=left]Sample Output[/align]
Case #1: 100 50 200 Case #2: -1 25 Case #3: 10 -1
[align=left]Author[/align]
SYSU
[align=left]Source[/align]
2014 Multi-University Training Contest 9
[align=left]Recommend[/align]
We have carefully selected several similar problems for you: 5431 5430 5429 5428 5427
我们先把操作离线,并把timestamp离散化,
在线段树上记录时间戳,加入为1,出栈为-1
询问 _t 就是找最大的x使[x,_t]>=1
可以用线段树区间和,最大后缀和维护
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=next[p]) #define Lson (o<<1) #define Rson ((o<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define MEM2(a,i) memset(a,i,sizeof(a)); #define INF (2139062143) #define F (100000007) #define MAXN (50000+20) typedef long long ll; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} class SegmentTree { ll sumv[MAXN*4],addv[MAXN*4]; ll rsum[MAXN*4]; int n; public: SegmentTree(){MEM(sumv) MEM(rsum) } SegmentTree(int _n):n(_n){ MEM(sumv) MEM(rsum) } void mem(int _n) { n=_n; MEM(sumv) MEM(rsum) } void maintain(int o,int L,int R) { if (L>=R) return ; if (L<R) { sumv[o]=sumv[Lson]+sumv[Rson]; rsum[o]=max(rsum[Rson] , sumv[Rson] + rsum[Lson] ); } } int y1,y2,v; void update(int o,int L,int R) //y1,y2,v { if (y1<=L&&R<=y2) { rsum[o]=sumv[o]=v; } else{ int M=(R+L)>>1; if (y1<=M) update(Lson,L,M); else maintain(Lson,L,M); if (M< y2) update(Rson,M+1,R); else maintain(Rson,M+1,R); maintain(o,L,R); } } ll _sum,_t,_len; void query2(int o,int L,int R) { if (y1<=L&&R<=y2) { _sum+=sumv[o]; } else { int M=(L+R)>>1; if (y1<=M) query2(Lson,L,M); if (M< y2) query2(Rson,M+1,R); } } int query3(int o,int L,int R) { if (R<_t) { if (_len+rsum[o]<=0) { _len+=sumv[o]; return -1; } if (L==R) return R; } if (L==R) { return -1; } int M=(L+R)>>1,ans=-1; if (M< _t) { ans=query3(Rson,M+1,R); if (ans!=-1) return ans; } return query3(Lson,L,M); } void add(int l,int r,ll v) { y1=l,y2=r;this->v=v; update(1,1,n); } ll ask(int l,int r,int b=0) { _sum=0; y1=l,y2=r; switch(b) { case 1:query2(1,1,n);return _sum; case 2:_t=l;_len=0;return query3(1,1,n); default:break; } return -111; } void print() { For(i,n) cout<<ask(i,i,1)<<' '; cout<<endl; } }S; int n; char s[10]; struct com{ int p,w,t; }ask[MAXN]; int bb[MAXN]; int val[MAXN]; int main() { // freopen("H.in","r",stdin); // freopen(".out","w",stdout); int kcase=0; while (scanf("%d",&n)==1&&n) { memset(val,-1,sizeof(val)); For(i,n) { scanf("%s",s); if (s[1]=='u') { ask[i].p=1; scanf("%d%d",&ask[i].w,&ask[i].t); } else if (s[1]=='o') { ask[i].p=2; scanf("%d",&ask[i].t); } else { ask[i].p=3; scanf("%d",&ask[i].t); } bb[i]=ask[i].t; } sort(bb+1,bb+1+n); int m=unique(bb+1,bb+1+n)-(bb+1); S.mem(n+2); printf("Case #%d:\n",++kcase); For(i,n) { int pos=lower_bound(bb+1,bb+1+m,ask[i].t)-(bb)+1; if (ask[i].p==1) S.add(pos,pos,1),val[pos]=ask[i].w; else if (ask[i].p==2) S.add(pos,pos,-1); else { int t=S.ask(pos,pos,2) ; printf("%d\n",t>=1?val[t]:-1 ); } } } return 0; }
相关文章推荐
- linux服务器常用部署命令
- shell函数参数
- Linux下boost库交叉编译
- shell for循环
- 运行shell脚本,错误bash: ./temp.sh: /bin/bash^M: bad interpreter: No such file or directory
- linux中fork()函数详解(原创!!实例讲解)
- shell script针对参数已经有配置好变量名称
- Linux 命令
- Linux图形界面与字符界面切换
- Linux Wireless基础知识
- bash 变量名中包含变量赋值方法
- xargs的用法--linux
- 希尔排序 shell sort
- Linux下几种文件传输命令 sz rz sftp scp
- org.apache.commons.lang下的工具类
- ubuntu安装hadoop
- Linux定时备份数据库与脚本加密
- 8-30 练习题
- centos nginx和svn开机自启动
- centos 单独安装nginx