样例过了,全wa
查看原帖
样例过了,全wa
361592
histcat楼主2024/10/20 19:52

rt

思路是先看做多能被几次全攻击一遍,最后一遍二分看最多能攻击到哪个

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int n, q, W;
int a[N];
int pre[N];
int po[64];
int read()
{
	int f = 1, x = 0;
	char ch = getchar();
	while(ch < '0' || ch > '9')
	{
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9')
	{
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return f * x;
}
int L, R, d;

struct SegmentTree
{
	int tree[N << 2], lazytag[N << 2];
	//小写代表线段树控制的区间,大写代表查询/修改区间 
	
	void update(int u)
	{
		tree[u] = tree[u * 2] + tree[u * 2 + 1];
	}
	
	void build(int u, int l, int r)
	{
		if(l == r)
		{
			tree[u] = a[l];
			return;
		}
		int mid = (l + r) >> 1;
		build(u * 2, l, mid);
		build(u * 2 + 1, mid + 1, r);
		update(u);
	}
	
	void pushdown(int u, int l, int r)
	{
		int mid = (l + r) >> 1;
		tree[u * 2] += (mid - l + 1) * lazytag[u];
		tree[u * 2 + 1] += (r - mid) * lazytag[u];
		lazytag[u * 2] += lazytag[u];
		lazytag[u * 2 + 1] += lazytag[u];
		lazytag[u] = 0;
	}
	
	bool InRange(int l, int r, int L, int R)
	{
		return (l >= L) && (r <= R);
	}
	
	bool OutRange(int l, int r, int L, int R)
	{
		return (l > R) || (r < L);
	}
	
	void modify(int u, int l, int r, int L, int R, int k)
	{
		if(InRange(l, r, L, R))
		{
			tree[u] += (r - l + 1) * k;
			lazytag[u] += k;
			return;
		}
		if(OutRange(l, r, L, R)) return;
		pushdown(u, l, r);
		int mid = (l + r) >> 1;
		modify(u * 2, l, mid, L, R, k), modify(u * 2 + 1, mid + 1, r, L, R, k);		
		update(u);
	}
	
	int query(int u, int l, int r, int L, int R)
	{
		if(InRange(l, r, L, R)) return tree[u];
		if(OutRange(l, r, L, R)) return 0;
		pushdown(u, l, r);
		int mid = (l + r) >> 1;
		return query(u * 2, l, mid, L, R) + query(u * 2 + 1, mid + 1, r, L, R);
	}
	
}seg;


signed main()
{
	freopen("wxyt.in", "r", stdin);
	freopen("wxyt.out", "w", stdout);
	po[0] = 1;
	for(int i = 1;i < 64;i++) po[i] = po[i - 1] * 2;
	n = read(), q = read(), W = read();
	for(int i = 1;i <= n;i++)
	{
		a[i] = read();
		pre[i] = pre[i - 1] + a[i];
	}
	while(q --)
	{
		L = read(), R = read(), d = read();
		seg.modify(1, 1, n, L, R, d);
		int sum = pre[n] + seg.query(1, 1, n, 1, n);
		int cnt = 0;
		int lstsum = 0;
		while(sum < W)
		{
			cnt++;
			lstsum = sum;
			sum = sum * 2 + sum;
		}
		
		int w = W - lstsum;
		int l = 0, r = n;
		while(l < r)
		{
			int mid = (l + r + 1) >> 1;
			if((pre[mid] + seg.query(1, 1, n, 1, mid)) * po[cnt] < w)
				l = mid;
			else
				r = mid - 1;
		}
		printf("%lld\n", cnt * n + l);
		
	}
	
	return 0;
}
2024/10/20 19:52
加载中...