题目大意:
关于网络阻塞命令延迟的处理。
命令就分为三种对栈的处理。
但是如果接收到一个操作,它后面的操作都要先取消不做,再做这个操作,再做之前取消了的操作。
思路分析:
题目也就转化成了,给出一个时间t接收到peak操作,找到第一个最大的 l ,使得 sum[l - t] > 0...
然后的问题我们就是如何确定最大的l。
我们记录sum的同时再记录一个右边最大。
然后我们在查询的时候,就通过右边最大和sum ,确定区间。
当s==e的时候就是所求的。
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define maxn 50005 using namespace std; typedef long long ll; struct node { char type; int t,val; }save[maxn]; int res[maxn<<2]; int rsum[maxn<<2]; int id[maxn]; int n; void pushup(int num) { res[num]=res[num<<1]+res[num<<1|1]; rsum[num]=max(rsum[num<<1|1],res[num<<1|1]+rsum[num<<1]); } void update(int num,int s,int e,int pos,int val,int tid) { if(s==e) { res[num]+=val; rsum[num]+=val; id[s]=tid; if(val==-1)id[s]=0; return; } int mid=(s+e)>>1; if(pos<=mid)update(lson,pos,val,tid); else update(rson,pos,val,tid); pushup(num); } int query(int num,int s,int e,int l,int r) { if(l<=s && r>=e) return res[num]; int mid=(s+e)>>1; if(r<=mid)return query(lson,l,r); else if(l>mid)return query(rson,l,r); else return query(lson,l,mid)+query(rson,mid+1,r); } int peak(int num,int s,int e,int l,int r,int t) { if(l<=s && r>=e) { if(s==e) { return id[s]; } else { int mid=(s+e)>>1; if(rsum[num<<1|1]>t) { int tmp = peak(rson,l,r,t); if(tmp)return tmp; } else if(rsum[num<<1]>t-res[num<<1|1]){ int tmp = peak(lson,l,r,t-res[num<<1|1]); if(tmp)return tmp; } } return 0; } int mid=(s+e)>>1; if(r<=mid) { int tmp = peak(lson,l,r,t); if(tmp)return tmp; } else if(l>mid){ int tmp = peak(rson,l,r,t); if(tmp)return tmp; } else { int tmp = peak(rson,mid+1,r,t); if(tmp)return tmp; tmp = peak(lson,l,mid,t-query(1,1,n,mid+1,r)); if(tmp)return tmp; } } int x[maxn]; int main() { int CASE=1; while(scanf("%d",&n)!=EOF && n) { memset(res,0,sizeof res); memset(rsum,0,sizeof rsum); memset(id,0,sizeof id); printf("Case #%d:\n",CASE++); char str[10]; for(int i=1;i<=n;i++) { int v,time; scanf("%s",str); if(str[1]=='u')scanf("%d%d",&v,&time); else scanf("%d",&time); save[i].type=str[1];save[i].val=v;save[i].t=time; x[i]=save[i].t; } sort(x+1,x+1+n); for(int i=1;i<=n;i++) save[i].t=lower_bound(x+1,x+1+n,save[i].t)-x; for(int i=1;i<=n;i++) { if(save[i].type=='u') update(1,1,n,save[i].t,1,i); else if(save[i].type=='o') update(1,1,n,save[i].t,-1,i); else { int pos = save[i].t-1; if(pos<1)puts("-1"); else { if(query(1,1,n,1,pos)>0) { printf("%d\n",save[peak(1,1,n,1,pos,0)].val); } else puts("-1"); } } } } return 0; }
Hdu 4967 Handling the Past (线段树)
时间: 2024-10-12 20:45:41