1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| #pragma GCC optimize("inline") #pragma GCC optimize(3) #include <bits/stdc++.h>
using namespace std;
const int maxn = 1e+5 + 5; const int maxb = maxn / 650 + 5;
int n, m, a[maxn], blo, bel[maxn]; int mx[maxb], tag[maxb], f[maxb][maxn]; int bkt[maxb][maxn], in[maxb], out[maxb];
inline int rd() { register int x = 0, c = getchar(); while (!isdigit(c)) c = getchar(); while (isdigit(c)) x = x * 10 + (c ^ 48), c = getchar(); return x; } int find(int *fa, int x) { return fa[x] ? fa[x] = find(fa, fa[x]) : x; } inline void modify(const int &l, const int &r, const int &x) { int lb = bel[l], rb = bel[r]; for (register int i = l; i <= r && i <= out[lb]; ++i) if (((a[i] = find(f[lb], a[i])) - tag[lb]) > x) { bkt[lb][a[i]]--; a[i] -= x; bkt[lb][a[i]]++; } for (register int i = lb + 1; i < rb; ++i) { if (mx[i] - tag[i] > (x << 1)) { for (register int j = 1; j <= x; ++j) { f[i][j + tag[i]] = j + tag[i] + x; bkt[i][f[i][j + tag[i]]] += bkt[i][j + tag[i]]; } tag[i] += x; } else { for (register int j = x + 1; j <= mx[i] - tag[i]; ++j) { f[i][j + tag[i]] = j + tag[i] - x; bkt[i][f[i][j + tag[i]]] += bkt[i][j + tag[i]]; } mx[i] = min(mx[i], x + tag[i]); } } if (lb != rb) { for (register int i = in[rb]; i <= r; ++i) { if (((a[i] = find(f[rb], a[i])) - tag[rb]) > x) { bkt[rb][a[i]]--; a[i] -= x; bkt[rb][a[i]]++; } } } } inline int query(const int &l, const int &r, const int &x) { int lb = bel[l], rb = bel[r], ret = 0; for (register int i = l; i <= r && i <= out[lb]; ++i) if (find(f[lb], a[i]) - tag[lb] == x) ret++; for (register int i = lb + 1; i < rb; ++i) { if (tag[i] + x <= mx[i]) ret += bkt[i][x + tag[i]]; } if (lb != rb) for (register int i = in[rb]; i <= r; ++i) if (find(f[rb], a[i]) - tag[rb] == x) ret++; return ret; }
int main() { n = rd(); m = rd(); blo = 650; for (register int i = 1; i <= n; ++i) { a[i] = rd(); bel[i] = (i - 1) / blo + 1; bkt[bel[i]][a[i]]++; if (!in[bel[i]]) in[bel[i]] = i; } for (int i = 1; i <= bel[n]; ++i) mx[i] = 1e+5, out[i] = i * blo; out[bel[n]] = n; int opt, l, r, x; while (m--) { opt = rd(); l = rd(); r = rd(); x = rd(); if (opt == 1) { modify(l, r, x); } else if (opt == 2) { printf("%d\n", query(l, r, x)); } } return 0; }
|