可能思路较奇怪的一种做法
#include<bits/stdc++.h>
#define lowb(x) x&(-x)
using namespace std;
const int N=2e5+666;
typedef long long ll;
struct node{
ll val,num;
node(){
}
node(ll x,ll y){
val=x,num=y;
return;
}
}now,q[N];
int n,c,top=1,tail;
ll s1[N],mx[N],s2[N];
void add(int x,ll data){//树状数组维护最值
while(x<=n){
mx[x]=max(mx[x],data);
x+=lowb(x);
}
return;
}
ll ask(int x,int y){
ll ans=0ll;
while(y>=x){
while(y-lowb(y)>=x){
ans=max(ans,mx[y]);
y-=lowb(y);
}
if(y<x)
break;
ans=max(ans,s2[y]);
y--;
}
return ans;
}
int main(){
int dx=0,dy=0,loc;
ll x;
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>c>>n;
for(int i=1;i<=n;++i){
cin>>c;
if(c==1){
cin>>x;
q[++tail]=node(x,x);
s2[++dy]=x;
s1[dy]=s1[dy-1]+x;//加入双端队列中
add(dy,x);
}
else if(c==2){
cin>>x;
now=q[top];
x+=now.val-now.num+s1[dx];//要在前缀和中二分,先加上前面的
loc=upper_bound(s1+dx+1,s1+dy+1,x)-s1-1;//二分寻找修改后位置
top+=(loc-dx);
dx=loc;
q[top].num=q[top].val-(x-s1[dx]);
}
else if(c==3){
cin>>x;
now=q[top];
x+=(now.val-now.num+s1[dx]);
loc=lower_bound(s1+dx+1,s1+dy+1,x)-s1-1;//二分同理
cout<<x-s1[loc]<<endl;
}
else
cout<<ask(dx+1,dy)<<endl;
}
return 0;
}
感觉时间复杂度nlog(n),六个输出样例都对
但是TLE 75 #9 #10 #11 #12 #20
https://www.luogu.com.cn/record/189681744
有没有热心大佬帮忙看一下Orz