[LOJ6279]数列分块入门 3
题目大意:
给你一个长度为$n(n\leq100000)$的序列$A$,支持进行以下两种操作:
1.将区间$[l,r]$中所有数加上$c$;
2.询问区间$[l,r]$中,严格小于$c$的最大数。
思路:
分块。
1 #include<cmath> 2 #include<cstdio> 3 #include<cctype> 4 #include<climits> 5 #include<algorithm> 6 inline int getint() { 7 register char ch; 8 register bool neg=false; 9 while(!isdigit(ch=getchar())) if(ch=='-') neg=true; 10 register int x=ch^'0'; 11 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 12 return neg?-x:x; 13 } 14 const int N=100001; 15 int val[N],tag[N],bel[N],s[N],begin[N],end[N]; 16 inline bool cmp(const int &a,const int &b) { 17 return val[a]+tag[bel[a]]<val[b]+tag[bel[b]]; 18 } 19 inline void modify(const int &l,const int &r,const int &c) { 20 if(bel[l]==bel[r]) { 21 for(register int i=l;i<=r;i++) val[i]+=c; 22 std::sort(&s[begin[bel[l]]],&s[end[bel[l]]]+1,cmp); 23 return; 24 } 25 for(register int i=l;bel[i]==bel[l];i++) val[i]+=c; 26 std::sort(&s[begin[bel[l]]],&s[end[bel[l]]]+1,cmp); 27 for(register int i=r;bel[i]==bel[r];i--) val[i]+=c; 28 std::sort(&s[begin[bel[r]]],&s[end[bel[r]]]+1,cmp); 29 for(register int i=bel[l]+1;i<bel[r];i++) tag[i]+=c; 30 } 31 inline int query(const int &l,const int &r,const int &c) { 32 int ret=INT_MIN; 33 bool flag=false; 34 if(bel[l]==bel[r]) { 35 for(register int i=l;i<=r;i++) { 36 if(val[i]+tag[bel[i]]<c) { 37 ret=std::max(ret,val[i]+tag[bel[i]]); 38 flag=true; 39 } 40 } 41 return flag?ret:-1; 42 } 43 for(register int i=l;bel[i]==bel[l];i++) { 44 if(val[i]+tag[bel[i]]<c) { 45 ret=std::max(ret,val[i]+tag[bel[i]]); 46 flag=true; 47 } 48 } 49 for(register int i=r;bel[i]==bel[r];i--) { 50 if(val[i]+tag[bel[i]]<c) { 51 ret=std::max(ret,val[i]+tag[bel[i]]); 52 flag=true; 53 } 54 } 55 for(register int i=bel[l]+1;i<bel[r];i++) { 56 const int pos=std::lower_bound(&s[begin[i]],&s[end[i]]+1,0,cmp)-&s[0]; 57 if(pos!=begin[i]) { 58 ret=std::max(ret,val[s[pos-1]]+tag[bel[s[pos-1]]]); 59 flag=true; 60 } 61 } 62 return flag?ret:-1; 63 } 64 int main() { 65 const int n=getint(),block=sqrt(n); 66 for(register int i=1;i<=n;i++) { 67 val[i]=getint(); 68 bel[i]=i/block+1; 69 s[i]=i; 70 if(!begin[bel[i]]) begin[bel[i]]=i; 71 end[bel[i]]=i; 72 } 73 for(register int i=bel[1];i<=bel[n];i++) { 74 std::sort(&s[begin[i]],&s[end[i]]+1,cmp); 75 } 76 for(register int i=0;i<n;i++) { 77 const int opt=getint(),l=getint(),r=getint(),&c=val[0]=getint(); 78 if(opt) { 79 printf("%d\n",query(l,r,c)); 80 } else { 81 modify(l,r,c); 82 } 83 } 84 return 0; 85 }