49pts求条,玄关
查看原帖
49pts求条,玄关
716260
SegmentTree_楼主2024/7/25 16:55

开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;
}
2024/7/25 16:55
加载中...