LOJ #6283. 数列分块入门 7

区间加,区间乘,单点查询。

跟线段树的差不多,为了避免精度问题要先乘再加。区别也和其他的差不多,残块暴力。然后就没什么了。scanf读int要& !

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 const int mod = 10007;
 7 
 8 int atag[350],mtag[350],v[100010],bl[100010];
 9 int n,blo,opt,l,r,c;
10 
11 void down(int x){
12     if(mtag[x]^1)
13         for(int i = (x-1)*blo+1;i <= min(n,x*blo);i++)
14             v[i] *= mtag[x],v[i] %= mod;
15     mtag[x] = 1;
16     if(atag[x])
17         for(int i = (x-1)*blo+1;i <= min(n,x*blo);i++)
18             v[i] += atag[x],v[i] %= mod;
19     atag[x] = 0;
20 }
21 
22 void add(int l,int r,int c){
23     if(bl[l] == bl[r]){
24         down(bl[l]);
25         for(int i = l;i <= r;i++)
26             v[i] += c,v[i] %= mod;
27         return;
28     }
29     down(bl[l]),down(bl[r]);
30     for(int i = l;i <= bl[l]*blo;i++)
31         v[i] += c,v[i] %= mod;
32     for(int i = (bl[r]-1)*blo+1;i <= r;i++)
33         v[i] += c,v[i] %= mod;
34     for(int i = bl[l]+1;i < bl[r];i++)
35         atag[i] += c,atag[i] %= mod;
36 }
37 
38 int ask(int x){
39     return (v[x]*mtag[bl[x]]%mod+atag[bl[x]])%mod;
40 }
41 
42 void mul(int l,int r,int c){
43     if(bl[l] == bl[r]){
44         down(bl[l]);
45         for(int i = l;i <= r;i++)
46             v[i] *= c,v[i] %= mod;
47         return;
48     }
49     down(bl[l]),down(bl[r]);
50     for(int i = l;i <= bl[l]*blo;i++)
51         v[i] *= c,v[i] %= mod;
52     for(int i = (bl[r]-1)*blo+1;i <= r;i++)
53         v[i] *= c,v[i] %= mod;
54     for(int i = bl[l]+1;i < bl[r];i++)
55         atag[i] *= c,atag[i] %= mod,
56         mtag[i] *= c,mtag[i] %= mod;    
57 }
58 
59 int main(){
60     scanf("%d",&n); blo = sqrt(n);
61     for(int i = 1;i <= n;i++){
62         scanf("%d",&v[i]);
63         v[i] %= mod;
64         bl[i] = (i-1)/blo+1;
65     }
66     for(int i = 1;i <= bl[n];i++)mtag[i] = 1;
67     for(int i = 1;i <= n;i++){
68         scanf("%d%d%d%d",&opt,&l,&r,&c);
69         switch(opt){
70             case 0:add(l,r,c);break;
71             case 1:mul(l,r,c);break;
72             case 2:printf("%d\n",ask(r));break;
73         }
74     }
75 return 0;
76 }

 

posted @ 2019-11-03 10:51  TIH_HIT  阅读(244)  评论(0编辑  收藏  举报