7 分,只过了一个点,其他 WA + RE。感觉越界但是没有问题
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define uint unsigned int
#define reg register
#define ld long double
#define uint unsigned int
#define ull unsigned long long
#define qint const int&
#define qll const ll&
#define quint cosnt uint&
#define qull const ull&
struct FastIO {
inline FastIO& operator >> (int& x) {
x = 0;
char f = 0, ch = getchar();
while (ch > '9' || ch < '0') f |= (ch == '-'), ch = getchar();
while (ch <= '9' && ch >= '0') x = x * 10 + ch - 48, ch = getchar();
return x = (f ? -x : x), *this;
}
inline FastIO& operator >> (long long& x) {
x = 0;
char f = 0, ch = getchar();
while (ch > '9' || ch < '0') f |= (ch == '-'), ch = getchar();
while (ch <= '9' && ch >= '0') x = x * 10 + ch - 48, ch = getchar();
return x = (f ? -x : x), *this;
}
inline FastIO& operator >> (double& x) {
x = 0;
char f = 0, ch = getchar();
double d = 0.1;
while (ch > '9' || ch < '0') f |= (ch == '-'), ch = getchar();
while (ch <= '9' && ch >= '0') x = x * 10 + ch - 48, ch = getchar();
if (ch == '.') {
ch = getchar();
while (ch <= '9' && ch >= '0') x += d * (ch ^ 48), d *= 0.1, ch = getchar();
}
return x = (f ? -x : x), *this;
}
} rin;
inline int abs(qint x) {
return x < 0 ? -x : x;
}
inline int min(qint x, qint y) {
return x < y ? x : y;
}
inline int max(qint x, qint y) {
return x > y ? x : y;
}
const int N = 500010, V = 100010, BL = 800;
int n, m, a[N << 1], opt[N], l[N], r[N], x[N], ans[N];
int pos[N << 1], bl[(N << 1) / BL + 10], br[(N << 1) / BL + 10];
struct BLOCK {
int l, r, rt[V << 1], fa[N << 1], sz[V << 1], val[N << 1], lazytag, maxnum;
inline int root(int x) {
if (fa[x] == x) return fa[x];
else return fa[x] = root(fa[x]);
}
inline void merge(int x, int y) {
if (rt[y]) fa[rt[x]] = rt[y];
else rt[y] = rt[x], val[rt[y]] = y;
sz[y] += sz[x], rt[x] = sz[x] = 0;
}
inline void clear() {
for (reg int i = l; i <= r; ++i) {
a[i] = val[root(i)];
rt[a[i]] = sz[a[i]] = 0;
a[i] -= lazytag;
}
lazytag = 0;
for (reg int i = l; i <= r; ++i) fa[i] = 0;
}
inline void init() {
maxnum = 0;
for (reg int i = l; i <= r; ++i) {
if (!rt[a[i]]) rt[a[i]] = i, fa[i] = i, val[i] = a[i];
else fa[i] = rt[a[i]];
++sz[a[i]], maxnum = max(maxnum, a[i]);
}
}
inline void Tmerge(int x) {
if (maxnum - lazytag < (x << 1)) {
for (reg int i = maxnum; i > x + lazytag; --i)
if (rt[i]) merge(i, i - x);
maxnum = min(maxnum, lazytag + x);
} else {
for (reg int i = lazytag + 1; i <= lazytag + x; ++i)
if (rt[i]) merge(i, i + x);
lazytag += x;
}
}
inline void Dmerge(int ql, int qr, int x) {
if (ql > qr) return;
clear();
for (reg int i = ql; i <= qr; ++i)
if (a[i] > x) a[i] -= x;
init();
}
inline int Tquery(int x) {
if (x + lazytag >= (V << 1)) return 0;
return sz[x + lazytag];
}
inline int Dquery(int ql, int qr, int x) {
reg int ans = 0;
for (reg int i = ql; i <= qr; ++i)
if (val[root(i)] - lazytag == x) ++ans;
return ans;
}
} block;
signed main() {
ios :: sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
rin >> n >> m;
for (reg int i = 1; i <= n; ++i) rin >> a[i];
for (reg int i = 1; i <= m; ++i) rin >> opt[i] >> l[i] >> r[i] >> x[i];
for (reg int i = 1; i <= n; ++i) pos[i] = (i - 1) / BL + 1;
for (reg int i = 1; i <= pos[n]; ++i) {
bl[i] = (i - 1) * BL + 1;
br[i] = min(n, i * BL);
}
for (reg int i = 1; i <= pos[n]; ++i) {
block.l = bl[i], block.r = br[i];
block.init();
for (reg int j = 1; j <= m; ++j) {
if (opt[j] == 1) {
if (l[j] <= block.l && r[j] >= block.r) block.Tmerge(x[j]);
else block.Dmerge(max(l[j], block.l), min(r[j], block.r), x[j]);
} else {
if (l[j] <= block.l && r[j] >= block.r) ans[j] += block.Tquery(x[j]);
else ans[j] += block.Dquery(max(l[j], block.l), min(r[j], block.r), x[j]);
}
}
}
for (reg int i = 1; i <= m; ++i) if (opt[i] == 2) cout << ans[i] << "\n";
return 0;
}