數列分塊入門3
阿新 • • 發佈:2018-12-12
#include<stdio.h> #include<string.h> #include<string> #include<iostream> #include<algorithm> #include<queue> #include<math.h> #include<map> #include<vector> #include<stack> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int N=100005; int a[N],be[N],add[N]; int n,mod; vector<int>v[N/10]; void reset(int x) { v[x].clear(); for(int i=(x-1)*mod+1; i<=min(x*mod,n); i++) v[x].push_back(a[i]); sort(v[x].begin(),v[x].end()); } void ADD(int l,int r,int k) { int i; for(i=l; i<=min(r,mod*be[l]); i++) a[i]+=k; reset(be[l]); if(be[r]!=be[l]) { for(i=(be[r]-1)*mod+1; i<=r; i++) a[i]+=k; reset(be[r]); } for(i=be[l]+1; i<=be[r]-1; i++) add[i]+=k; } int qurey(int l,int r,int c) { int i,ans=-1; for(i=l; i<=min(r,mod*be[l]); i++) if(a[i]+add[be[l]]<c) ans=max(ans,a[i]+add[be[l]]); if(be[l]!=be[r]) for(i=(be[r]-1)*mod+1; i<=r; i++) if(a[i]+add[be[r]]<c) ans=max(ans,a[i]+add[be[r]]); for(i=be[l]+1; i<=be[r]-1; i++) { int temp=c-add[i],num; num=lower_bound(v[i].begin(),v[i].end(),temp)-v[i].begin(); num--; if(v[i][num]<temp) ans=max(ans,v[i][num]+add[i]); } return ans; } int main() { int i,temp,l,r,k,op; scanf("%d",&n); mod=sqrt(n); for(i=1; i<=n; i++) scanf("%d",&a[i]); for(i=1; i<=n; i++) be[i]=(i-1)/mod+1; for(i=1; i<=n; i++) v[be[i]].push_back(a[i]); for(i=1; i<=be[n]; i++) sort(v[i].begin(),v[i].end()); for(i=0; i<n; i++) { scanf("%d %d %d %d",&op,&r,&l,&k); if(op==0) ADD(r,l,k); else printf("%d\n",qurey(r,l,k)); } return 0; }