70pts TLE 求调
查看原帖
70pts TLE 求调
589961
steambird楼主2024/10/21 07:42
#include <bits/stdc++.h>
using namespace std;

constexpr int N = 2e5+4, NS = 8e5+4;

inline long long maxi(long long a, long long b) {
	return a > b ? a : b;
}

inline long long mini(long long a, long long b) {
	return a < b ? a : b;
}

int lrange[NS], rrange[NS];
long long val[NS], lazy[NS];
bool ovrd[NS];

#define lch (root<<1)
#define rch ((root<<1)|1)
#define mids() int mid = (lrange[root] + rrange[root]) >> 1
#define lcall lch, maxi(lrange[root], l), mini(mid, r)
#define rcall rch, maxi(mid+1, l), mini(rrange[root], r)

int n,q;
long long w,a[N];

void pushup(int root) {
	if (ovrd[lch] || ovrd[rch] || (val[lch] + val[rch]) > w) {
		ovrd[root] = true;
		val[root] = 0;
	} else {
		ovrd[root] = false;
		val[root] = val[lch] + val[rch];
	}
}

void build(int root, int l, int r) {
	if (l > r) return;
	lrange[root] = l;
	rrange[root] = r;
	if (l == r) {
		val[root] = a[l];
		return;
	}
	mids();
	build(lch, l, mid);
	build(rch, mid+1, r);
	pushup(root);
}

int length(int root) {
	return rrange[root] - lrange[root] + 1;
}

void modify(int root, long long ud) {
	__int128 tmp = (__int128)(val[root]) + 1ll * ud * length(root);
	if (tmp > w) ovrd[root] = true;
	else val[root] = tmp;
	lazy[root] += ud;
}

void pushdown(int root) {
	modify(lch, lazy[root]);
	modify(rch, lazy[root]);
//	val[lch] += lazy[root];
//	lazy[lch] += lazy[root];
//	val[rch] += lazy[root];
//	lazy[rch] += lazy[root];
	lazy[root] = 0;
}

void update(int root, int l, int r, long long ud) {
	if (l > r) return;
	if (lrange[root] >= l && rrange[root] <= r) {
		modify(root, ud);
		return;
	}
	pushdown(root);
	mids();
	update(lcall, ud); update(rcall, ud);
	pushup(root);
}

// Seek for a position <= given threshold, as far as it can:
int lookup(int root, long long thr, long long extra) {
//	cerr << "Call lookup@" << root << " [" << lrange[root] << "," << rrange[root] << "] for " << thr << ", extra " << extra << endl;
	if (thr <= 0) return 0;
	if (lrange[root] == rrange[root]) {
		__int128 ival = (__int128)(val[root]) * extra;
		if ((!ovrd[root]) && ival < thr) return lrange[root];
		else return 0;
	}
	pushdown(root);
	//mids();
	int rresult;
	__int128 ival = (__int128)(val[lch]) * extra;
	if ((!ovrd[lch]) && ival < thr) {
		rresult = lookup(rch, thr - ival, extra);
		if (rresult == 0) return rrange[lch];
		else return rresult;
	}
	return lookup(lch, thr, extra);
}

int main() {
//#ifndef ONLINE_JUDGE
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
//#endif

	cin>>n>>q>>w;
	for (int i = 1; i <= n; i++) {
		cin>>a[i];
	}
	build(1, 1, n);
	for (int qs = 0; qs < q; qs++) {
		int loz, roz;
		long long d;
		cin>>loz>>roz>>d;
		update(1, loz, roz, d);
		// Search rows to suffer. When suffering x rounds
		// actually equal to (2^x -1) rounds.
		int l = 0, r = 63, ans = 0;
		__int128 basis = val[1];	// Rooted.
		long long reduced = 0;
		if (!ovrd[1]) {
			while (l <= r) {
				int mid = (l+r) >> 1;
				__int128 times = (1ll<<mid)-1;
				if (basis * times < w) {
					l = mid + 1;
					ans = mid;
					reduced = basis * times;
				} else {
					r = mid - 1;
				}
			}
		}
//		cerr << "Expected complete round *" << ans << ", where " << reduced << endl;
		int final = ans*n;
		int sch = lookup(1, w - reduced, 1ll<<ans);
//		cerr << "Looked up " << sch << endl;
		cout<<(final+sch)<<'\n';
	}
	cout<<flush;
	return 0;
}
2024/10/21 07:42
加载中...