分块 (区间修改,区间查询

比较常规的操作,用树状数组和线段树等都行。复杂度就不分析了

题目链接https://loj.ac/problem/6279

 1 #include<bits/stdc++.h>
 2 
 3 
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn = 1e5+10;
 7 const int inf = 0x3f3f3f3f;
 8 int dir[10][10] = {{1,0},{-1,0},{0,1},{0,-1}};
 9 ll sum[maxn],a[maxn],lz[maxn];
10 int opt,l,r,c,n,t,L[maxn],R[maxn],pos[maxn];
11 
12 inline int read()
13 {
14     char ch = getchar(); ll k = 0, f = 1;
15     while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
16     while(ch >= '0' && ch <= '9') {k = (k<<1) + (k<<3) + ch - '0'; ch = getchar();}
17     return k * f;
18 }
19 
20 inline void add(int l,int r,int c)//添加
21 {
22     if(pos[l] == pos[r])
23     {
24         for(int i = l; i <= r; ++i) a[i] += c;
25         sum[pos[l]] += (r - l + 1) * c;
26     }
27     
28     else
29     {
30         for(int i = l; i <= R[pos[l]]; ++i) a[i] += c;
31         sum[pos[l]] += (R[pos[l]] - l + 1) * c;
32         for(int i = L[pos[r]]; i <= r; ++i) a[i] += c;
33         sum[pos[r]] += (r - L[pos[r]] + 1) * c;
34         for(int i = pos[l] + 1; i <= pos[r] - 1; ++i) sum[i] += (R[i] - L[i] +1 ) * c, lz[i] += c;
35     }
36 
37 }
38 
39 inline ll findy(int l,int r,int c)//查询
40 {
41     ll ans = 0;
42     if(pos[l] == pos[r])
43     {
44         for(int i = l; i <= r; ++i) ans += (a[i] + lz[pos[l]]), ans %= (c + 1);
45     }
46     
47     else
48     {
49         for(int i = l; i <= R[pos[l]]; ++i) ans += (a[i] + lz[pos[l]]), ans %= (c + 1);
50         for(int i = L[pos[r]]; i <= r; ++i) ans += (a[i] + lz[pos[r]]), ans %= (c + 1);
51         for(int i = pos[l] + 1; i <= pos[r] - 1; ++i)
52         {
53             ans += sum[i], ans %= (c + 1);
54         }
55         
56     }
57     return ans %= (c + 1);
58 }
59 
60 int main()
61 {
62     n=read();
63     for(int i = 1; i <= n; ++i) cin>>a[i];
64     t = sqrt(n);
65     for(int i = 1; i <= t; ++i)
66     {
67         L[i] = (i-1) * t + 1;
68         R[i] = i * t;
69     }
70     
71     if(R[t] != n) t++, L[t] = R[t - 1] + 1 ,R[t] = n;
72     for(int i = 1; i <= t; ++i)
73     {
74         for(int j = L[i]; j <= R[i]; ++j)
75         {
76             pos[j] = i; sum[i] += a[j];
77         }
78         
79     }
80 
81     for(int i = 1; i <= n; ++i)
82     {
83         opt = read(); l = read(); r = read(); c=read();
84         if(opt == 0) add(l, r, c);
85         else cout<<findy(l, r, c)<<endl;
86 
87     }
88     return 0;
89 }

 

posted @ 2020-07-31 00:32  YanMingA  阅读(242)  评论(0编辑  收藏  举报