分块
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //fen kuai 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int maxn = 200010; 5 const int inf = 0x3f3f3f3f; 6 int n, m, SZ; 7 int a[maxn], bc[maxn], Max[maxn]; 8 9 void update(int p, int v){ 10 int tp = (p - 1) / SZ + 1; 11 a[p] = v; 12 int temp = -inf; 13 for(int i = (tp - 1) * SZ + 1; i <= tp * SZ; i++){ 14 temp = max(temp, a[i]); 15 } 16 Max[tp] = temp; 17 } 18 19 int query(int l, int r){ 20 int ans = -inf; 21 int pl = (l - 1) / SZ + 1; 22 for(int i = l; i <= min(r, pl * SZ); i++){ 23 ans = max(ans, a[i]); 24 } 25 int pr = (r - 1) / SZ + 1; 26 if(pl != pr){ 27 for(int i = (pr - 1) * SZ + 1; i <= r; i++){ 28 ans = max(ans, a[i]); 29 } 30 } 31 for(int i = pl + 1; i < pr; i++){ 32 ans = max(ans, Max[i]); 33 } 34 return ans; 35 } 36 37 int main(){ 38 while(scanf("%d %d", &n, &m) != EOF){ 39 memset(Max, -inf, sizeof Max); 40 SZ = sqrt(n * 1.0); 41 for(int i = 1; i <= n; i++){ 42 scanf("%d", &a[i]); 43 bc[i] = (i - 1) / SZ + 1; 44 Max[bc[i]] = max(Max[bc[i]], a[i]); 45 } 46 while(m--){ 47 char op[4]; 48 int l, r; 49 scanf("%s %d %d", op, &l, &r); 50 if(op[0] == 'Q') { 51 printf("%d\n", query(l, r)); 52 }else{ 53 update(l, r); 54 } 55 } 56 } 57 return 0; 58 }
A Simple Problem with Integers
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //fen kuai 2 #include <iostream> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstring> 6 using namespace std; 7 #define LL long long 8 const int maxn = 100010; 9 LL a[maxn], atag[maxn]; 10 LL sum[maxn]; 11 int n, m, SZ; 12 13 LL query(int l, int r){ 14 LL ans = 0; 15 int pl = (l - 1) / SZ + 1; 16 int pr = (r - 1) / SZ + 1; 17 for(int i = l; i <= min(r, pl * SZ); i++){ 18 ans += a[i] + atag[pl]; 19 } 20 if(pl != pr){ 21 for(int i = (pr - 1) * SZ + 1; i <= r; i++){ 22 ans += a[i] + atag[pr]; 23 } 24 } 25 for(int i = pl + 1; i < pr; i++){ 26 ans += sum[i]; 27 } 28 return ans; 29 } 30 31 void update(int l, int r, LL c){ 32 int pl = (l - 1) / SZ + 1; 33 int pr = (r - 1) / SZ + 1; 34 for(int i = l; i <= min(r, pl * SZ); i++){ 35 a[i] += c; 36 sum[pl] += c; 37 } 38 if(pl != pr){ 39 for(int i = (pr - 1) * SZ + 1; i <= r; i++){ 40 a[i] += c; 41 sum[pr] += c; 42 } 43 } 44 for(int i = pl + 1; i < pr; i++){ 45 sum[i] += c * SZ; 46 atag[i] += c; 47 } 48 } 49 50 int main(){ 51 while(scanf("%d %d", &n, &m) != EOF){ 52 SZ = sqrt(n * 1.0); 53 int j = 1; 54 for(int i = 1; i <= n; i++){ 55 sum[i] = 0; 56 atag[i] = 0; 57 scanf("%lld", &a[i]); 58 sum[j] += a[i]; 59 if(i % SZ == 0) j++; 60 } 61 while(m--){ 62 char op[4]; 63 int x, y; 64 LL c; 65 scanf("%s %d %d", op, &x, &y); 66 if(op[0] == 'Q'){ 67 printf("%lld\n", query(x, y)); 68 }else{ 69 scanf("%lld", &c); 70 update(x, y, c); 71 } 72 } 73 } 74 return 0; 75 }
Paint The Wall
参考:https://www.cnblogs.com/swm8023/archive/2012/09/23/2698780.html
带懒标记的分块
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // lazy 分块 2 #include <bits/stdc++.h> 3 using namespace std; 4 const int maxn = 100010; 5 6 int c[maxn], ov[maxn]; 7 map<int, int> mp[maxn]; 8 int n, m, SZ; 9 10 void pushdown(int id){ 11 if(ov[id] != -1){ 12 for(int i = id * SZ; i < min((id + 1) * SZ, n); i++) c[i] = ov[id]; 13 mp[id].clear(); 14 mp[id][ov[id]] = min((id + 1) * SZ, n) - id * SZ; 15 ov[id] = -1; 16 } 17 } 18 19 void update(int l, int r, int z){ 20 int pl = l / SZ, pr = r / SZ; 21 pushdown(pl); 22 for(int i = l; i <= min(r, (pl + 1) * SZ - 1); i++){ 23 mp[pl][c[i]]--; 24 c[i] = z; 25 mp[pl][z]++; 26 } 27 if(pl != pr){ 28 pushdown(pr); 29 for(int i = pr * SZ; i <= r; i++){ 30 mp[pr][c[i]]--; 31 c[i] = z; 32 mp[pr][z]++; 33 } 34 } 35 for(int i = pl + 1; i < pr; i++) ov[i] = z; 36 } 37 int query(int l, int r, int z){ 38 int res = 0; 39 int pl = l / SZ, pr = r / SZ; 40 pushdown(pl); 41 for(int i = l; i <= min(r, (pl + 1) * SZ - 1); i++) if(c[i] == z) res++; 42 if(pl != pr) { 43 pushdown(pr); 44 for(int i = pr * SZ; i <= r; i++) if(c[i] == z) res++; 45 } 46 for(int i = pl + 1; i < pr; i++){ 47 if(ov[i] == -1){ 48 if(mp[i].find(z) != mp[i].end()) res += mp[i][z]; 49 }else if(ov[i] == z) res += min((i + 1) * SZ, n) - i * SZ; 50 } 51 return res; 52 } 53 int main(){ 54 while(scanf("%d %d", &n, &m) != EOF){ 55 SZ = sqrt(n * 1.0); 56 memset(ov, -1, sizeof ov); 57 for(int i = 0; i < n; i++) mp[i].clear(); 58 for(int i = 0; i < n; i++){ 59 scanf("%d", &c[i]); 60 mp[i / SZ][c[i]]++; 61 } 62 while(m--){ 63 int op, l, r, z; 64 scanf("%d %d %d %d", &op, &l, &r, &z); 65 if(op == 1){ 66 update(l, r, z); 67 }else{ 68 printf("%d\n", query(l, r, z)); 69 } 70 } 71 } 72 return 0; 73 }