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 93 94 95 96
|
#include <bits/stdc++.h> using namespace std; #define resetIO(x) \ freopen(#x ".in", "r", stdin), freopen(#x ".out", "w", stdout) #define debug(fmt, ...) \ fprintf(stderr, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) template <class _Tp> inline _Tp& read(_Tp& x) { bool sign = false; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) sign |= (ch == '-'); for (x = 0; isdigit(ch); ch = getchar()) x = x * 10 + (ch ^ 48); return sign ? (x = -x) : x; } template <class _Tp> inline void write(_Tp x) { if (x < 0) putchar('-'), x = -x; if (x > 9) write(x / 10); putchar((x % 10) ^ 48); } using ll = long long; const int MAXN = 1e6 + 10, MAXM = 1e5 + 10, MAXQ = 5e5 + 10; int n, m, q, blk, a[MAXN], fa[MAXN], siz[MAXM], val[MAXN], ans[MAXQ], repr[MAXM]; struct Query { int op, l, r, k, i; } qr[MAXQ]; inline int getfa(int x) { return fa[x] == x ? x : fa[x] = getfa(fa[x]); } inline void change(int x, int y) { if (!repr[x]) return; if (repr[y]) { fa[repr[x]] = repr[y]; siz[y] += siz[x]; siz[x] = repr[x] = 0; } else { val[repr[y] = repr[x]] = y; siz[y] = siz[x]; siz[x] = repr[x] = 0; } } inline void solve(int sl, int sr) { int mxn = *max_element(a + sl, a + sr + 1), lzy = 0; fill(siz, siz + m + 1, 0); fill(val, val + m + 1, 0); fill(repr, repr + m + 1, 0); for (int i = sl; i <= sr; ++i) { if (!repr[a[i]]) repr[a[i]] = fa[i] = i, val[i] = a[i], siz[a[i]] = 1; else fa[i] = repr[a[i]], ++siz[a[i]]; } for (int t = 1; t <= q; ++t) { int l = qr[t].l, r = qr[t].r, k = qr[t].k; if (r < sl || sr < l) continue; if (qr[t].op == 1) { if (mxn - lzy <= k) continue; if (l <= sl && sr <= r) { if (k > (mxn - lzy) / 2) { for (int i = k + 1; i <= mxn - lzy; ++i) change(i + lzy, i - k + lzy); mxn = min(mxn, k + lzy); } else { for (int i = k; i >= 0; --i) change(i + lzy, i + k + lzy); lzy += k; } } else { for (int i = sl; i <= sr; ++i) { int w = val[getfa(i)]; a[i] = w - lzy, siz[w] = repr[w] = 0; if (l <= i && i <= r && a[i] > k) a[i] -= k; } mxn = *max_element(a + sl, a + sr + 1), lzy = 0; fill(val + sl, val + sr + 1, 0); for (int i = sl; i <= sr; ++i) { if (!repr[a[i]]) repr[a[i]] = fa[i] = i, val[i] = a[i], siz[a[i]] = 1; else fa[i] = repr[a[i]], ++siz[a[i]]; } } } else { if (k + lzy > m) continue; if (l <= sl && sr <= r) { ans[qr[t].i] += siz[k + lzy]; } else { for (int i = sl; i <= sr; ++i) if (l <= i && i <= r) ans[qr[t].i] += val[getfa(i)] - lzy == k; } } } } signed main() { read(n), read(q), m = 1e5 + 1, blk = ceil(sqrt(n)); for (int i = 1; i <= n; ++i) read(a[i]); for (int i = 1; i <= q; ++i) read(qr[i].op), read(qr[i].l), read(qr[i].r), read(qr[i].k), qr[i].i = i; for (int i = 1; i <= n; i += blk) solve(i, min(n, i + blk - 1)); for (int i = 1; i <= q; ++i) if (qr[i].op == 2) write(ans[i]), putchar('\n'); return 0; }
|