[LOJ6278]数列分块入门 2

题目大意:
  给你一个长度为$n(n\leq 50000)$的序列$A$,支持进行以下两种操作:
    1.将区间$[l,r]$中所有数加上$c$;
    2.询问区间$[l,r]$中小于$c^2$的数的个数。
思路:
  分块。
  对于整块的数据打标记,零散的数据直接修改。同时维护同一块中从小到大的顺序,统计时对于同一块中的数二分答案,零散的数直接统计。

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<algorithm>
 5 #include<functional>
 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=50001;
15 int val[N],s[N],tag[N],bel[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=0;
33     val[0]=c*c;
34     if(bel[l]==bel[r]) {
35         for(register int i=l;i<=r;i++) {
36             if(val[i]+tag[bel[i]]<val[0]) ret++;
37         }
38         return ret;
39     }
40     for(register int i=l;bel[i]==bel[l];i++) {
41         if(val[i]+tag[bel[i]]<val[0]) ret++;
42     }
43     for(register int i=r;bel[i]==bel[r];i--) {
44         if(val[i]+tag[bel[i]]<val[0]) ret++;
45     }
46     for(register int i=bel[l]+1;i<bel[r];i++) {
47         ret+=std::lower_bound(&s[begin[i]],&s[end[i]]+1,0,cmp)-&s[begin[i]];
48     }
49     return ret;
50 }
51 int main() {
52     const int n=getint(),block=sqrt(n);
53     for(register int i=1;i<=n;i++) {
54         val[i]=getint();
55         bel[i]=i/block;
56         s[i]=i;
57         if(!begin[bel[i]]) begin[bel[i]]=i;
58         end[bel[i]]=i;
59     }
60     for(register int i=0;i<=bel[n];i++) {
61         std::sort(&s[begin[i]],&s[end[i]]+1,cmp);
62     }
63     for(register int i=0;i<n;i++) {
64         const int opt=getint(),l=getint(),r=getint(),c=getint();
65         if(opt) {
66             printf("%d\n",query(l,r,c));
67         } else {
68             modify(l,r,c);
69         }
70     }
71     return 0;
72 }

 

posted @ 2018-02-12 21:17  skylee03  阅读(129)  评论(0编辑  收藏  举报