[LOJ6280]数列分块入门 4

题目大意:
  给你一个长度为$n(n\leq50000)$的序列$A$,支持进行以下两种操作:
​    1.将区间$[l,r]$中所有数加上$c$;
    2.询问区间$[l,r]$在模$c+1$意义下的和。
思路:
  分块。

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cctype>
 4 typedef long long int64;
 5 inline int getint() {
 6     register char ch;
 7     register bool neg=false;
 8     while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
 9     register int x=ch^'0';
10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
11     return neg?-x:x;
12 }
13 const int N=50001;
14 int bel[N],begin[N],end[N];
15 int64 val[N],tag[N],sum[N];
16 inline int64 calc(const int &x) {
17     return val[x]+tag[bel[x]];
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++) {
22             val[i]+=c;
23             sum[bel[i]]+=c;
24         }
25         return;
26     }
27     for(register int i=l;bel[i]==bel[l];i++) {
28         val[i]+=c;
29         sum[bel[i]]+=c;
30     }
31     for(register int i=r;bel[i]==bel[r];i--) {
32         val[i]+=c;
33         sum[bel[i]]+=c;
34     }
35     for(register int i=bel[l]+1;i<bel[r];i++) {
36         tag[i]+=c;
37         sum[i]+=c*(end[i]-begin[i]+1);
38     }
39 }
40 inline int query(const int &l,const int &r,const int &mod) {
41     int ret=0;
42     if(bel[l]==bel[r]) {
43         for(register int i=l;i<=r;i++) ret=(ret+calc(i))%mod;
44         return ret;
45     }
46     for(register int i=l;bel[i]==bel[l];i++) ret=(ret+calc(i))%mod;
47     for(register int i=r;bel[i]==bel[r];i--) ret=(ret+calc(i))%mod;
48     for(register int i=bel[l]+1;i<bel[r];i++) ret=(ret+sum[i])%mod;
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         sum[bel[i]]+=val[i];
57         if(!begin[bel[i]]) begin[bel[i]]=i;
58         end[bel[i]]=i;
59     }
60     for(register int i=0;i<n;i++) {
61         const int opt=getint(),l=getint(),r=getint(),&c=val[0]=getint();
62         if(opt) {
63             printf("%d\n",query(l,r,c+1));
64         } else {
65             modify(l,r,c);
66         }
67     }
68     return 0;
69 }

 

posted @ 2018-02-15 13:55  skylee03  阅读(102)  评论(0编辑  收藏  举报