提交时间:2022-02-10 08:01:11

运行 ID: 44723

//使用set去重,这样可以找到严格小于x的前驱 #include<bits/stdc++.h> using namespace std; const int N=500056; int bl[N],n,v[N],atag[N],block; set<int>S[N]; void Add(int l,int r,int val) { for(int i=l; i<=min(bl[l]*block,r); i++) { S[bl[l]].erase(v[i]); v[i]+=val; S[bl[l]].insert(v[i]); } if(bl[l]!=bl[r]) for(int i=(bl[r]-1)*block+1; i<=r; i++) { S[bl[r]].erase(v[i]); v[i]+=val; S[bl[r]].insert(v[i]); } for(int i=bl[l]+1; i<=bl[r]-1; i++) atag[i]+=val; } int Query(int l,int r,int val) { int ans=-1; for(int i=l; i<=min(bl[l]*block,r); i++) if(v[i]+atag[bl[l]]<val) ans=max(ans,v[i]+atag[bl[l]]); if(bl[l]!=bl[r]) { for(int i=(bl[r]-1)*block+1; i<=r; i++) if(v[i]+atag[bl[r]]<val) ans=max(ans,v[i]+atag[bl[r]]); } for(int i=bl[l]+1; i<=bl[r]-1; i++) { int x=val-atag[i]; set<int>::iterator it=S[i].lower_bound(x); if(it==S[i].begin()) continue; --it; ans=max(ans,*it+atag[i]); } return ans; } int main() { scanf("%d",&n); block=sqrt(n); for(int i=1; i<=n; i++) { bl[i]=(i-1)/block+1; scanf("%d",&v[i]); S[bl[i]].insert(v[i]); } for(int opt,l,r,c,i=1; i<=n; i++) { scanf("%d%d%d%d",&opt,&l,&r,&c); if(!opt) Add(l,r,c); else printf("%d\n",Query(l,r,c)); } return 0; }