rt。理由:询问3可以转化为一道经典的倍增题目:对于一个序列a,求最大的i,使得第一项到第i项的和小于一个给定的值,可以将二分的O(logN)优化为O(log答案)。详见代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6;
struct node{
long long l,r;
}a[maxn];
long long c,q,in1,in2,tot,ltot=1,dele,len,d[maxn];
bool b[maxn];
deque<int>que;
int main(){
cin>>c>>q;
while(q--){
cin>>in1;
if(in1==1){
cin>>in2;
a[++tot]={1,in2};
while(!que.empty()&&a[que.back()].r<=in2) que.pop_back();
que.push_back(tot);
len+=in2;
d[tot]=d[tot-1]+in2;
}
else if(in1==2){
cin>>in2;
dele+=in2;
while(in2){
if(a[ltot].r-a[ltot].l+1>in2){
a[ltot].l+=in2;
in2=0;
}else{
in2-=a[ltot].r-a[ltot].l+1;
b[ltot++]=1;
}
}
}else if(in1==3){
cin>>in2;
in2+=dele;
//d[i]是前缀和数组
//查询最大的i,使得 d[i]<in2,使用倍增算法,非常经典
long long p=1,k=0,sum=0;
while(p)
if(k+p<=tot&&sum+d[k+p]-d[k]<in2)
sum+=d[k+p]-d[k],k+=p,p*=2;
else p/=2;
printf("%d\n",in2-d[k]);
}else{
while(b[que.front()]) que.pop_front();
printf("%d\n",a[que.front()].r);
}
}
return 0;
}