[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 }

 

posted @ 2018-02-15 11:51  skylee03  阅读(113)  评论(0编辑  收藏  举报