Rt。赛时只有第三个大样例没过
思路是用pair维护每一个x,first维护在真正的数组中其的下标,second是x的值。维护一个可删堆求最大值,查询某点用二分实现,删除和添加用nowl和nowr来确定当前范围
#include<bits/stdc++.h>
#define AC return 0;
#define sc(n) scanf("%lld",&(n))
#define pr(n) printf("%lld",(n))
#define hh puts("")
#define kg printf(" ")
#define se second
#define fi first
#define int long long
using namespace std;
vector<pair<int,int> > v;
priority_queue<int> q1,q2;
void ins(int k)
{
q1.push(k);
}
void del(int k)
{
q2.push(k);
}
int _max(int a,int b)
{
return a>b?a:b;
}
int ask()
{
while(!q1.empty() && !q2.empty() &&q1.top()==q2.top() ){q1.pop();q2.pop();}
return q1.top();
}//可删堆(懒人专享)
signed main()
{
int c,q;
sc(c),sc(q);
int nowl=0,nowr=0,tot=0;
while(q--)
{
int opt;
sc(opt);
if(opt==4)
{
pr(ask());hh;
}
if(opt==1)
{
int a;sc(a);
ins(a);
nowr+=a;
v.push_back({nowr,a});
}
if(opt==2)
{
int a;sc(a);
nowl+=a;
while(nowl>=v[tot].first)
{
del(v[tot].second);
++tot;
}
}
if(opt==3)
{
int a;sc(a);
int to=nowl+a;
int l=tot,r=v.size();
while(l<r)
{
int mid=(l+r)>>1;
if(v[mid].first<to)l=mid+1;
else r=mid;
}
if(to-v[l-1].first)
pr(to-v[l-1].first);
else pr(v[l-1].second);
hh;
}
}
AC
}