开O2还会 RE #11
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define i128 __int128
#define ull unsigned long long
#define lid (id << 1)
#define rid (id << 1 | 1)
//#define int long long
const int N = 1e6+5, M = 1e6+5;
namespace io {
#define fastio ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
const int SIZE = (1 << 21) + 1;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c, qu[55]; int f, qr;
// #define gc() (iS == iT ? (iT = (iS = ibuf) + fread (ibuf, 1, SIZE, stdin), (iS == iT ? EOF : *iS ++)) : *iS ++)
#define gc() getchar()
inline void flush () { fwrite (obuf, 1, oS - obuf, stdout); oS = obuf; }
inline void putc (char x) { *oS ++ = x; if (oS == oT) flush (); }
template <class I> inline void read(I &x){ for (f = 1, c = gc(); c < '0' || c > '9'; c = gc()) if (c == '-') f = -1; for (x = 0; c <= '9' && c >= '0'; c = gc()) x = x * 10 + (c & 15); x *= f; }
template <class I> inline void write(I x) { if (!x) putc ('0'); if (x < 0) putc ('-'), x = -x; while (x) qu[++ qr] = x % 10 + '0', x /= 10; while (qr) putc (qu[qr --]); }
struct Flusher_ {~Flusher_(){flush();}}io_flusher_;
}
using io::read;
using io::write;
using io::putc;
namespace tianyu{
int n, m;
int len, tot;
int a[N];
int op[M], ql[M], qr[M], qx[M];
int pa[N], val[N], ji[N], siz[N];
int mx, lazy;
int ans[M];
inline int find(int x){
return pa[x] == x ? x : pa[x] = find(pa[x]);
}
inline void merge(int x, int y){
if (ji[y]){
pa[ji[x]] = ji[y];
}
else{
ji[y] = ji[x];
val[ji[y]] = y;
}
siz[y] += siz[x];
siz[x] = ji[x] = 0;
}
inline void build(int bid){
int bl = (bid - 1) * len + 1, br = (bid == tot ? n : bid * len);
mx = INT_MIN;
lazy = 0;
for (int i = bl;i <= br;i++){
mx = max(mx, a[i]);
if (!ji[a[i]]){
ji[a[i]] = i;
pa[i] = i;
val[i] = a[i];
}
else{
pa[i] = ji[a[i]];
}
++siz[a[i]];
}
}
inline void change1(int x){
if (2 * x > mx - lazy){
// for (int i = x + 1 + lazy;i <= mx;++i) if (ji[i]) merge(i, i - x);
for (int i = mx;i >= x + 1 + lazy;--i) if (ji[i]) merge(i, i - x);
mx = min(mx, x + lazy);
}
else{
for (int i = lazy + 1;i <= lazy + x;++i) if (ji[x]) merge(i, i + x);
// for (int i = lazy + x;i >= lazy;--i) if (ji[x]) merge(i, i + x);
lazy += x;
}
}
inline void change2(int bid, int l, int r, int x){
int bl = (bid - 1) * len + 1, br = (bid == tot ? n : bid * len);
l = max(l, bl), r = min(r, br);
for (int i = bl;i <= br;++i){
int tmp = val[find(i)];
a[i] = tmp - lazy;
ji[tmp] = siz[tmp] = 0;
}
for (int i = bl;i <= br;i++) val[i] = 0;
for (int i = l;i <= r;++i) if (a[i] > x) a[i] -= x;
build(bid);
}
inline int query1(int x){
return siz[x + lazy];
}
inline int query2(int bid, int l, int r, int x){
int bl = (bid - 1) * len + 1, br = (bid == tot ? n : bid * len);
l = max(l, bl), r = min(r, br);
int cnt = 0;
for (int i = l;i <= r;++i){
if (val[find(i)] - lazy == x){
++cnt;
}
}
return cnt;
}
void awa(){
read(n), read(m);
len = sqrt(n);
tot = n / len + (bool)(n % len);
for (int i = 1;i <= n;i++){
read(a[i]);
}
for (int i = 1;i <= m;++i){
read(op[i]), read(ql[i]), read(qr[i]), read(qx[i]);
}
for (int bi = 1;bi <= tot;++bi){
if (bi > 1){
memset(ji, 0, sizeof ji);
memset(siz, 0, sizeof siz);
}
mx = INT_MIN;
lazy = 0;
build(bi);
int bl = (bi - 1) * len + 1, br = (bi == tot ? n : bi * len);
for (int qi = 1;qi <= m;++qi){
int qop = op[qi], qql = ql[qi], qqr = qr[qi], qqx = qx[qi];
if (bl > qqr || br < qql) continue;
if (qop == 1){
if (qql <= bl && br <= qqr) change1(qqx);
else change2(bi, qql, qqr, qqx);
}
else{
if (qqx + lazy > 1e5 + 1) continue;
if (qql <= bl && br <= qqr) ans[qi] += query1(qqx);
else ans[qi] += query2(bi, qql, qqr, qqx);
}
}
}
for (int i = 1;i <= m;i++){
if (op[i] == 2) write(ans[i]), putc('\n');
}
}
}
signed main(){
// fastio;
int T = 1;
while (T--){
tianyu::awa();
}
return 0;
}