线段树二分 MLE and WA。
查看原帖
线段树二分 MLE and WA。
902351
Little_x_starTYJ楼主2024/10/23 18:46

感觉要用高精度一样。。。。

#include <bits/stdc++.h>
using namespace std;
#define int __int128
#define intt int
inline int read() {
	int k = 0;
	char c = getchar();
	while (c < '0' || c > '9')
		c = getchar();
	while (c >= '0' && c <= '9')
		k = (k << 1) + (k << 3) + (c ^ 48), c = getchar();
	return k;
}
inline int write(int k) {
	if (k > 9)
		write(k / 10);
	intt t = k % 10;
	putchar(t + '0');
}
int a[200010], n, q, w, k, ans, tree[800010], lazy[800010];
inline void buildTree(int k, int l, int r) {
	if (l == r) {
		tree[k] = a[l];
		return;
	}
	int mid = l + r >> 1;
	buildTree(2 * k, l, mid);
	buildTree(2 * k + 1, mid + 1, r);
	tree[k] = tree[2 * k] + tree[2 * k + 1];
}
inline int query(int k, int l, int r, int x, int y) {
	if (l == x && r == y) {
		return tree[k] + lazy[k] * (r - l + 1);
	}
	if (lazy[k]) {
		lazy[2 * k] += lazy[k];
		lazy[2 * k + 1] += lazy[k];
		lazy[k] = 0;
	}
	int mid = l + r >> 1, res;
	if (y <= mid)
		res = query(2 * k, l, mid, x, y);
	else if (x > mid)
		res = query(2 * k + 1, mid + 1, r, x, y);
	else
		res = query(2 * k, l, mid, x, mid) + query(2 * k + 1, mid + 1, r, mid + 1, y);
	tree[k] = tree[2 * k] + tree[2 * k + 1] + lazy[2 * k] * (mid - l + 1) + lazy[2 * k + 1] * (r - mid);
	return res;
}
inline void update(int k, int l, int r, int x, int y, int z) {
	if (l == x && r == y) {
		lazy[k] += z;
		return;
	}
	if (lazy[k]) {
		lazy[2 * k] += lazy[k];
		lazy[2 * k + 1] += lazy[k];
		lazy[k] = 0;
	}
	int mid = l + r >> 1;
	if (y <= mid)
		update(2 * k, l, mid, x, y, z);
	else if (x > mid)
		update(2 * k + 1, mid + 1, r, x, y, z);
	else
		update(2 * k, l, mid, x, mid, z), update(2 * k + 1, mid + 1, r, mid + 1, y, z);
	tree[k] = tree[2 * k] + tree[2 * k + 1] + lazy[2 * k] * (mid - l + 1) + lazy[2 * k + 1] * (r - mid);
}
inline int qmi(int a, int b) {
	int res = 1;
	while (b) {
		if (b & 1)
			res = res * a;
		a = a * a;
		b >>= 1;
	}
	return res;
}

int qpow = 1;
inline bool check(int x) {
	return k * (qmi(2, x) - 1) >= w;
}
inline bool check2(int x) {
	return query(1, 1, n, 1, x) * qpow >= w;
}
signed main() {
	n = read(), q = read(), w = read();
	for (int i = 1; i <= n; i++)
		a[i] = read();
	buildTree(1, 1, n);
	int l, r, d, temp = w;
	while (q--) {
		w = temp;
		l = read(), r = read(), d = read();
		update(1, 1, n, l, r, d);
		k = query(1, 1, n, 1, n);
		int ll = 1, rr = w / k + 1, mid;
		while (ll < rr) {
			mid = ll + rr >> 1;
			if (check(mid))
				rr = mid;
			else
				ll = mid + 1;
		}
		qpow = qmi(2, ll - 1);
		ans = (ll - 1) * n;
		//ll - 1 即为整的攻击。
		w -= (ll - 1) * k;
		ll = 1, rr = n;
		while (ll < rr) {
			mid = ll + rr >> 1;
			if (check2(mid))
				rr = mid;
			else
				ll = mid + 1;
		}
		write(ans + ll - 1), puts("");
		ans = 0;
	}
	return 0;
}
2024/10/23 18:46
加载中...