社区讨论

WA求调

P13977数列分块入门 2参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mkl7otir
此快照首次捕获于
2026/01/19 21:39
上个月
此快照最后确认于
2026/01/19 21:51
上个月
查看原帖
rt,只WA了第1个点。
~蒟蒻没学过分块因此这个分块都是自己手搓的,可能和正常人写的不太一样~
CPP
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define unll unsigned long long
#define bint __int128
#define set_q priority_queue
#define unmp unordered_map
mt19937_64 mrand((unll) std::chrono::steady_clock::now().time_since_epoch().count());

inline ll in () {
	ll x = 0; bool f = false; char ch = getchar();
	while (ch < '0' || ch > '9') {f |= ch == '-'; ch = getchar();}
	while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
	return f ? -x : x;
}

const ll p = 1000000007, inf = 1ll << 60ll, infless = -(1ll << 60ll);

inline ll quickpow (const ll &a, const ll &n) {
	ll res = 1ll, t = a;
	for (ll y = n; y > 0; y >>= 1) {
		if (y & 1) {
			res *= t;
			res %= p;
		}
		t *= t;
		t %= p;
	}
	return res;
}

const int N = 200100, M = 520;

int test, n, pos[N], cnt, len, b[N];
ll ans = 0ll, a[N];

struct block {
	int l, r;
	vector<ll> f;
	ll t = 0ll;
} c[N];

#define val(i) a[i] + c[pos[i]].t

inline void update (int p) {
	c[p].f.clear();
	for (int i = c[p].l; i <= c[p].r; i++) {
		c[p].f.push_back(a[i]);
	}
	sort(c[p].f.begin(), c[p].f.end());
}

inline void build (int l, int r) {
	if (r - l + 1 <= len) {
		cnt++;
		for (int i = l; i <= r; i++) {
			pos[i] = cnt;
		}
		c[cnt].l = l, c[cnt].r = r;
		c[cnt].t = 0;
		b[l] = 1;
		b[r] = 2;
		update(cnt);
		return;
	}
	int k = l + len - 1;
	cnt++;
	for (int i = l; i <= k; i++) {
		pos[i] = cnt;
	}
	b[l] = 1, b[k] = 2;
	c[cnt].l = l, c[cnt].r = k;
	c[cnt].t = 0;
	update(cnt);
	build(k + 1, r);
}

inline void modify (int l, int r, ll &v) {
	if (pos[l] == pos[r]) {
		for (int i = l; i <= r; i++) {
			a[i] += v;
		}
		update(pos[l]);
		return;
	}
	int lstpl = pos[l], lstpr = pos[r];
	int i = l, j = r;
	if (b[l] != 1) {
		for (i = l; i <= n && i <= r && b[i] != 1; i++) {
			a[i] += v;
		}
		update(lstpl);
	}
	if (b[r] != 2) {
		for (j = r; j && j >= l && b[j] != 2; j--) {
			a[j] += v;
		}
		update(lstpr);
	}
	for (int d = pos[i]; d <= pos[j]; d++) {
		c[d].t += v;
	}
}

inline ll query (int l, int r, ll v) {
	if (pos[l] == pos[r]) {
		ll cnt = 0;
		for (int i = l; i <= r; i++) {
			if (val(i) < v) {
				cnt++;
			}
		}
		return cnt;
	}
	ll res = 0;
	int i = l, j = r;
	for (; i <= n && i <= r && b[i] != 1; i++) {
		if (val(i) < v) {
			res++;
		}
	}
	for (; j && j >= l && b[j] != 2; j--) {
		if (val(j) < v) {
			res++;
		}
	}
	for (int d = pos[i]; d <= pos[j]; d++) {
		res += lower_bound(c[d].f.begin(), c[d].f.end(), v - c[d].t) - c[d].f.begin();
	}
	return res;
}

inline void solve () {
	ans = 0ll;
	//solve clear !
	n = in();
	for (int i = 1; i <= n; i++) {
		a[i] = in();
	}
	len = (int)sqrt(n);
	cnt = 0;
	build(1, n);
	for (int i = 1; i <= n; i++) {
		ll opt = in(), l = in(), r = in(), v = in();
		if (opt == 0) {
			modify(l, r, v);
		} else {
			printf("%lld\n", query(l, r, v * v));
		}
	}
	return;
}

int main() {
	for (test = 1; test--; solve());
	return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...