P5511 RE 求条
  • 板块题目总版
  • 楼主pystraf11
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/6/25 22:06
  • 上次更新2025/6/26 22:07:37
查看原帖
P5511 RE 求条
1068414
pystraf11楼主2025/6/25 22:06
#include <bits/stdc++.h>
using namespace std;

using i64 = long long;
using ui64 = unsigned long long;
using i128 = __int128;
using ui128 = unsigned __int128;
using f4 = float;
using f8 = double;
using f16 = long double;

template<class T>
bool chmax(T &a, const T &b){
	if(a < b){ a = b; return true; }
	return false;
}

template<class T>
bool chmin(T &a, const T &b){
	if(a > b){ a = b; return true; }
	return false;
}

constexpr int inf = 2e9, L = 256;

struct node {
	int l, r, v;
	inline node() {}
	inline node(int _l, int _r, int _v) : l(_l), r(_r), v(_v) {}
	inline int size() { return r - l + 1; }
	
	inline void apply(int tmin, int tmax) {
		if (v < tmin) v = tmin;
        if (v > tmax) v = tmax;
	}
	
	inline pair<node, node> split(int p) {
		return {node(l, p - 1, v), node(p, r, v)};
	}
	
	inline int query(int _v) { return (v < _v ? size() : 0); }
};

struct block {
	int len, tmin, tmax;
	vector<int> pre;
	vector<node> seg, sorted, tmp;
	array<int, L> cnt;
	
	inline block() {}
	inline void build() {
		len = seg.size(), tmin = 0, tmax = inf;
	    sorted = seg, sort();
	    
	    pre.resize(len + 1), pre[0] = 0;
        for (int i = 0; i < len; i++) pre[i + 1] = pre[i] + sorted[i].size();
	}
	
	inline void init(int n) {
		len = 1, tmin = 0, tmax = inf;
		seg = {node(0, n - 1, 0)};
		sorted = {node(0, n - 1, 0)};
		pre.resize(2);
		pre[0] = 0, pre[1] = n;
	}
	
	inline int bl() { return seg[0].l; }
	inline int br() { return seg[len - 1].r; }
	inline int size() { return br() - bl() + 1; }
	
	inline void sort() {
		tmp.resize(len);
		for (int i = 0; i < L; i++) cnt[i] = 0;
		for (int i = 0; i < len; i++) cnt[sorted[i].v & 0xff]++;
		for (int i = 1; i < L; i++) cnt[i] += cnt[i - 1];
		for (int i = len - 1; i >= 0; i--) tmp[--cnt[sorted[i].v & 0xff]] = sorted[i];
		
		for (int i = 0; i < L; i++) cnt[i] = 0;
		for (int i = 0; i < len; i++) cnt[(tmp[i].v >> 8) & 0xff]++;
		for (int i = 1; i < L; i++) cnt[i] += cnt[i - 1];
		for (int i = len - 1; i >= 0; i--) sorted[--cnt[(tmp[i].v >> 8) & 0xff]] = tmp[i];
		
		for (int i = 0; i < L; i++) cnt[i] = 0;
		for (int i = 0; i < len; i++) cnt[(sorted[i].v >> 16) & 0xff]++;
		for (int i = 1; i < L; i++) cnt[i] += cnt[i - 1];
		for (int i = len - 1; i >= 0; i--) tmp[--cnt[(sorted[i].v >> 16) & 0xff]] = sorted[i];
		
		for (int i = 0; i < L; i++) cnt[i] = 0;
		for (int i = 0; i < len; i++) cnt[(tmp[i].v >> 24) & 0xff]++;
		for (int i = 1; i < L; i++) cnt[i] += cnt[i - 1];
		for (int i = len - 1; i >= 0; i--) sorted[--cnt[(tmp[i].v >> 24) & 0xff]] = tmp[i];
	}
	
	inline void pushdown() {
		for (int i = 0; i < len; i++) {
			seg[i].apply(tmin, tmax);
			sorted[i].apply(tmin, tmax);
		}
		tmin = 0, tmax = inf;
	}
    
    inline int belong(int x) {
    	for (int i = 0; i < len; i++)
    	    if (seg[i].l <= x && x <= seg[i].r) return i;
    	return -1;
    }
    
    inline int query(int v) {
    	if (v > tmax) return size();
    	if (v <= tmin) return 0;
    	int l = 0, r = len;
        while (l ^ r) {
            const int mid = (l + r) >> 1;
            if (sorted[mid].v < v) l = mid + 1;
            else r = mid;
        }
        return pre[l];
    }
    
    inline int query(int l, int r, int v) {
        int bl = belong(l), br = belong(r), res = 0;
    	pushdown();
    	if (bl == br) return (seg[bl].v < v ? r - l + 1 : 0);

    	res += seg[bl].split(l).second.query(v);
    	for (int i = bl + 1; i < br; i++) res += seg[i].query(v);
    	res += seg[br].split(r + 1).first.query(v);
    	return res;
    }
    
    inline void update(int t1, int t2) {
	    if (t1 > tmin) {
	        tmin = t1;
	        if (t1 > tmax) tmax = t1;
	    }
	
	    if (t2 < tmax) {
	        tmax = t2;
	        if (t2 < tmin) tmin = t2;
	    }
	}
	
	inline bool update(int l, int r, int t1, int t2) {
		int bl = belong(l), br = belong(r);
		pushdown();
		if (bl == br) {
			tmp.clear();
			for (int i = 0; i < bl; i++) tmp.push_back(seg[i]);
			auto [lef, rem] = seg[bl].split(l);
			if (lef.size() > 0) tmp.push_back(lef);
			if (rem.size() > 0) {
				auto [mid, rig] = rem.split(r + 1);
				if (mid.size() > 0) {
					mid.apply(t1, t2);
					tmp.push_back(mid);
				}
				if (rig.size() > 0) tmp.push_back(rig);
			}
			for (int i = bl + 1; i < len; i++) tmp.push_back(seg[i]);
			seg = tmp;
			return seg.size() >= L;
		}
		
		tmp.clear();
		for (int i = 0; i < bl; i++) tmp.push_back(seg[i]);
		
		auto [nl, nr] = seg[bl].split(l);
		if (nl.size() > 0) tmp.push_back(nl);
		if (nr.size() > 0) {
			nr.apply(t1, t2);
			tmp.push_back(nr);
		}
		
		for (int i = bl + 1; i < br; i++) {
			node cur = seg[i];
			cur.apply(t1, t2);
			tmp.push_back(cur);
		}
		
		auto [ml, mr] = seg[br].split(r + 1);
		if (ml.size() > 0) {
			ml.apply(t1, t2);
			tmp.push_back(ml);
		}
		if (mr.size() > 0) tmp.push_back(mr);
		for (int i = br + 1; i < len; i++) tmp.push_back(seg[i]);
		
		seg = tmp;
		return seg.size() >= L;
 	}
 	
};

struct DS {
	int n;
	list<block> rec;
	using iter = list<block>::iterator;
	
	inline DS() {}
	inline DS(int _n) : n(_n) {
		block tmp; tmp.init(n);
		rec.push_back(tmp);
	}
	
	inline iter belong(int x) {
		for (iter it = rec.begin(); it != rec.end(); it++)
		    if (it->bl() <= x && x <= it->br()) return it;
		return rec.end();
	}
	
	inline void refact(iter b) {
		int half = b->len / 2;
		block tmp;
		tmp.seg.resize(b->len - half);
		for (int i = half; i < b->len; i++) tmp.seg[i - half] = b->seg[i];
		
		b->seg.resize(half);
		b->build(), tmp.build();
		rec.insert(next(b), tmp);
	}
	
	inline int query(int l, int r, int v) {
		iter bl = belong(l), br = belong(r);
		if (bl == br) return bl->query(l, r, v);
		
		int res = bl->query(l, bl->br(), v) + br->query(br->bl(), r, v);
		for (auto it = next(bl); it != br; it++) res += it->query(v);
		return res;
	}
	
	inline void _update(iter b, int l, int r, int t1, int t2) {
		if (b->update(l, r, t1, t2)) refact(b);
		else b->build();
	}
	
	inline void update(int l, int r, int t1, int t2) {
		iter bl = belong(l), br = belong(r);
		if (bl == br) return _update(bl, l, r, t1, t2);
		_update(bl, l, bl->br(), t1, t2);
		_update(br, br->bl(), r, t1, t2);
		for (auto it = next(bl); it != br; it++) it->update(t1, t2);
	}
};

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	
	int n, q, c;
	cin >> n >> q >> c;
	
	DS ds(n);
	for (int i = 0, op, l, r, h, lst = 0; i < q; i++) {
		cin >> op >> l >> r >> h;
		l ^= lst, r ^= lst, h ^= lst;
		l--, r--;
		if (l > r) continue;
		
		if (op == 1) {
			cout << (lst = ds.query(l, r, h)) << endl;
			lst *= c;
		}
		
		if (op == 2) ds.update(l, r, 0, h);
		if (op == 3) ds.update(l, r, h, inf);
	}
	
	return 0;
}
2025/6/25 22:06
加载中...