区间修改,区间查询前驱。
TLE无数,我觉得这代码最精髓的就是block=1000。
谜一样的1000。
两个启示:
- 块内可以维护数据结构,比如set
- 可以换换块大小,自造数据测试时间
//Stay foolish,stay hungry,stay young,stay simple
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<set>
#define R register
using namespace std;
const int nINF=-(1<<29);
const int MAXN=500005;
set<int> b[1000];
void Out(int x)
{
if(x<0)
{
putchar('-');x=-x;
}
if(x>9)Out(x/10);
putchar(x%10+'0');
}
inline int read_d(){
int ret=0,f=1;char c;
while(c=getchar(),!isdigit(c)) f=c=='-'?-1:1;
while(isdigit(c)){
ret*=10;ret+=c-'0';
c=getchar();
}
return f*ret;
}
int n;
int a[MAXN],inc[MAXN],l[MAXN],
r[MAXN],bl[MAXN];
int block,num;
void reset(int id){
b[id].clear();
for(R int i=l[id];i<=r[id];i++) b[id].insert(a[i]);
}
void build(){
// block=sqrt(n);
// block>>=1;
block=1000;//玄学?!?!?!?!?
num=n/block;
if(n%block) num++;
for(int i=1;i<=n;i++){
l[i]=(i-1)*block+1;
r[i]=i*block;
}
r[num]=n;
for(R int i=1;i<=n;i++)
bl[i]=(i-1)/block+1;
for(R int i=1;i<=n;i++) b[bl[i]].insert(a[i]);
}
void updata(int x,int y,int w){
if(bl[x]==bl[y]){
for(int i=x;i<=y;i++)
b[bl[i]].erase(a[i]),a[i]+=w,b[bl[i]].insert(a[i]);
return;
}
for(R int i=x;i<=r[bl[x]];i++){
b[bl[i]].erase(a[i]);
a[i]+=w;
b[bl[i]].insert(a[i]);
}
for(R int i=bl[x]+1;i<=bl[y]-1;i++)
inc[i]+=w;
for(R int i=l[bl[y]];i<=y;i++){
b[bl[i]].erase(a[i]);
a[i]+=w;
b[bl[i]].insert(a[i]);
}
}
int query(int x,int y,int w){
int ret=nINF;
if(bl[x]==bl[y]){
ret=-1;
for(int i=x;i<=y;i++){
int v=a[i]+inc[bl[i]];
if(v<w) ret=max(ret,v);
}
return ret;
}
for(R int i=x;i<=r[bl[x]];i++){
int v=a[i]+inc[bl[i]];
if(v<w) ret=max(ret,v);
}
for(R int i=l[bl[y]];i<=y;i++){
int v=a[i]+inc[bl[i]];
if(v<w) ret=max(ret,v);
}
for(R int i=bl[x]+1;i<=bl[y]-1;i++){
set<int>::iterator it = b[i].lower_bound(w-inc[i]);
if(it==b[i].begin())continue;
--it;
ret = max(ret,*it+inc[i]);
}
return ret;
}
int main(){
// freopen("in.txt","r",stdin);
// freopen("test.txt","w",stdout);
n=read_d();
for(R int i=1;i<=n;i++) a[i]=read_d();
build();
for(R int i=1;i<=n;i++){
int q,x,y,z;
q=read_d();
x=read_d();
y=read_d();
z=read_d();
if(q==0) updata(x,y,z);
else {
int ans=query(x,y,z);
if(ans==nINF) puts("-1");
else Out(ans),putchar('
');
}
}
return 0;
}