题目:
给出一个长为 n 的数列,以及 n 个操作,操作涉及区间加法,询问区间内小于某个值 x 的前驱(比其小的最大元素)。
对于 100% 的数据:1≤n≤105,−231≤others、ans≤231−1
代码:
#include <bits/stdc++.h>
//#define int long long
using namespace std;
const int N = 100010;
int n,a[N],add[N],B,d[N],ans;
set<int> g[110];
inline int read(){
char c=0;
int f=1,x=0;
while(c<'0'||c>'9'){
if (c=='-')
f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return f*x;
}
int main(){
n=read();
B=sqrt(n);
for(int i=1;i<=n;i++){
a[i]=read();
d[i]=(i-1)/B+1;
g[d[i]].insert(a[i]);
}
for(int i=1;i<=n;i++){
int opt,l,r,c;
opt=read();
l=read();
r=read();
c=read();
if(!opt){
if(d[l]!=d[r]){
for(int j=l;j<=B*d[l];j++){
g[d[l]].erase(a[j]);
a[j]+=c;
g[d[l]].insert(a[j]);
}
for(int j=d[l]+1;j<=d[r]-1;j++)
add[j]+=c;
for(int j=B*(d[r]-1)+1;j<=r;j++){
g[d[r]].erase(a[j]);
a[j]+=c;
g[d[r]].insert(a[j]);
}
}
else{
if(r-l+1==B) add[d[l]]+=c;
else
for(int j=l;j<=r;j++){
g[d[l]].erase(a[j]);
a[j]+=c;
g[d[l]].insert(a[j]);
}
}
}
else{
ans=-1;
if(d[l]!=d[r]){
for(int j=l;j<=B*d[l],r;j++){
int val=a[j]+add[d[l]];
if(val<c)
ans=max(ans,val);
}
for(int j=d[l]+1;j<=d[r]-1;j++){
int val=c-add[j];
set<int>::iterator it=g[j].lower_bound(val);
if(it==g[j].begin()) continue;
it--;
ans=max(ans,*it+add[j]);
}
for(int j=B*(d[r]-1)+1;j<=r;j++){
int val=a[j]+add[d[r]];
if(val<c)
ans=max(ans,val);
}
}
else{
for(int j=l;j<=min(B*d[l],r);j++){
int val=a[j]+add[d[l]];
if(val<c)
ans=max(ans,val);
}
for(int j=d[l]+1;j<=d[r]-1;j++){
int val=c-add[j];
set<int>::iterator it=g[j].lower_bound(val);
if(it==g[j].begin()) continue;
it--;
ans=max(ans,*it+add[j]);
}
}
printf("%d\n",ans);
}
}
return 0;
}
TLE 了