听说是线段树上套二分,可是不知道怎么写。
此份代码 60 pts。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 i128;
const int N = 2e5 + 10;
int n,q;
ll s,b[N];
i128 w;
i128 a[N],sum[N << 2],lzy[N << 2];
void pushup(int o){
sum[o] = sum[o << 1] + sum[o << 1 | 1];
}
void build(int o,int l,int r){
if (l == r){
sum[o] = a[l];
return;
}
int mid = (l + r) >> 1;
build(o << 1,l,mid);
build(o << 1 | 1,mid + 1,r);
pushup(o);
}
void pushdown(int o,int l,int r){
int mid = (l + r) >> 1;
sum[o << 1] += lzy[o] * (mid - l + 1);
sum[o << 1 | 1] += lzy[o] * (r - mid);
lzy[o << 1] += lzy[o];
lzy[o << 1 | 1] += lzy[o];
lzy[o] = 0;
}
void update(int o,int l,int r,int ql,int qr,i128 x){
if (ql <= l && r <= qr){
sum[o] += (r - l + 1) * x;
lzy[o] += x;
return;
}
int mid = (l + r) >> 1;
pushdown(o,l,r);
if (ql <= mid) update(o << 1,l,mid,ql,qr,x);
if (qr > mid) update(o << 1 | 1,mid + 1,r,ql,qr,x);
pushup(o);
}
i128 query(int o,int l,int r,int ql,int qr){
if (ql <= l && r <= qr)
return sum[o];
int mid = (l + r) >> 1;
i128 ret = 0;
pushdown(o,l,r);
if (ql <= mid) ret += query(o << 1,l,mid,ql,qr);
if (qr > mid) ret += query(o << 1 | 1,mid + 1,r,ql,qr);
return ret;
}
int main(){
freopen("wxyt4.in","r",stdin);
freopen("wxyt4.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> q >> s;
w = s;
for (int i = 1 ; i <= n ; i++) cin >> b[i];
for (int i = 1 ; i <= n ; i++) a[i] = b[i];
build(1,1,n);
for (int i = 1 ; i <= q ; i++){
int l,r;
ll d;
i128 e;
cin >> l >> r >> d;
e = d;
update(1,1,n,l,r,e);
ll level = 1;
int ans = 0;
i128 blood = w;
i128 all = query(1,1,n,1,n);
while(1){
if (blood <= all) break;
blood -= all;
all *= 2;
ans += n;
level *= 2;
}
int L = 1,R = n,tmid,p = 0;
while(L <= R){
tmid = (L + R) >> 1;
if (query(1,1,n,1,tmid) * level < blood){
p = tmid;
L = tmid + 1;
}else{
R = tmid - 1;
}
}
cout << ans + p << '\n';
}
return 0;
}