题目链接
思路:显然对于每个操作,只能被他之前的且时间小于他的操作所影响。
把所有的时间离散化之后,用时间为下标建立区间线段树,下标为 g g g的值为 s g s_g sg
枚举所有操作 ( o p , t , v ) (op,t,v) (op,t,v)
把入栈当成区间 [ t , n ] + 1 [t,n]+1 [t,n]+1,出栈为区间 [ t , n ] − 1 [t,n]-1 [t,n]−1
因为保证所有的操作是合法的,那么查询时刻T的栈顶元素的时候,此时线段树上下标为 t t t的值为 s x s_x sx,那么必然有一个位置 y y y满足 s x − s y > 0 s_x-s_y>0 sx−sy>0,那么此时的栈顶元素必然是由第一个时间点大于y的的操作产生的,模拟以上操作即可。
#include
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
struct uzi{
int op,t,v;
bool operator < (const uzi & T)const{
return t<T.t;
}
}p[N],q[N];
int n,T[N],ans[N],f[N];
int tr[N<<2],laz[N<<2];
#define mid (l+r>>1)
#define ls o<<1
#define rs o<<1|1
void pd(int o){
laz[ls]+=laz[o];
laz[rs]+=laz[o];
tr[ls]+=laz[o];
tr[rs]+=laz[o];
laz[o]=0;
return ;
}
void add(int o,int l,int r,int x,int y,int d){
if(l>=x && r<=y){
tr[o]+=d;
laz[o]+=d;
return ;
}
pd(o);
if(x<=mid)add(ls,l,mid,x,y,d);
if(y>mid)add(rs,mid+1,r,x,y,d);
tr[o]=min(tr[ls],tr[rs]);
return ;
}
int pa(int o,int l,int r,int d){
if(l==r && d-tr[o]>0)return l;
if(l==r)return -1;
pd(o);
if(d-tr[rs]>0)return pa(rs,mid+1,r,d);
if(d-tr[ls]>0)return pa(ls,l,mid,d);
return -1;
}
int get(int o,int l,int r,int x,int y,int d){
if(l>=x && r<=y){
return pa(o,l,r,d);
}
if(l>y||r<x|| l>r)return -1;
pd(o);
int an=-1;
if(mid<=y)an=max(an,get(rs,mid+1,r,x,y,d));
if(x<=mid)an=max(an,get(ls,l,mid, x,y,d));
return an;
}
int sa[N];
void adda(int p,int d){
for(;p<N;p+=p&-p)sa[p]+=d;
}
int geta(int p){
int sz=0;
for(;p;p-=p&-p)sz+=sa[p];
return sz;
}
set<pair<int,int>>s;
int ti[N];
int main() {
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>p[i].op>>p[i].t;
if(p[i].op==0)cin>>p[i].v;
}
for(int i=1;i<=n;i++)ti[i]=p[i].t;
sort(ti+1,ti+1+n);
int len=unique(ti+1,ti+1+n)-ti-1;
for(int i=1;i<=n;i++)p[i].t=lower_bound(ti+1,ti+1+len,p[i].t)-ti,f[p[i].t]=i;
int d=0;
for(int i=1;i<=n;i++){
if(p[i].op==0){
add(1,0,len,p[i].t,len,1);
s.insert({p[i].t,p[i].v});
adda(p[i].t,1);
}else if(p[i].op==1){
add(1,0,len,p[i].t,len,-1);
adda(p[i].t,-1);
}else{
int pos=get(1,0,len,0,p[i].t-1,geta(p[i].t));
assert(pos!=-1);
auto f=s.lower_bound({pos+1,0});
assert(f!=s.end());
cout<<(*f).se<<endl;
}
}
return 0;
}