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;
}