线段树上二分常数大需要快读,快读还T的加inline,我加inline快了430ms
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
void read(int &a){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||'9'<ch){
if(ch=='-')w=-1;
ch=getchar();
}
while('0'<=ch&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
a=s*w;
}
struct node{
int pre,l,r,tag;
}t[4*N];
int a[N];
inline int ls(int p){
return p<<1;
}
inline int rs(int p){
return p<<1|1;
}
inline void push_up(int p){
t[p].pre=t[ls(p)].pre+t[rs(p)].pre;
return;
}
inline void build(int p,int l,int r){
t[p].l=l,t[p].r=r,t[p].tag=0;
if(t[p].l==t[p].r){
t[p].pre=a[l];
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
push_up(p);
return;
}
inline void push_down(int p){
if(t[p].tag){
t[ls(p)].pre+=t[p].tag*(t[ls(p)].r-t[ls(p)].l+1);
t[rs(p)].pre+=t[p].tag*(t[rs(p)].r-t[rs(p)].l+1);
t[ls(p)].tag+=t[p].tag;
t[rs(p)].tag+=t[p].tag;
t[p].tag=0;
}
return;
}
inline void update(int p,int l,int r,int k){
if(l<=t[p].l&&t[p].r<=r){
t[p].tag+=k;
t[p].pre+=(t[p].r-t[p].l+1)*k;
return;
}
push_down(p);
int mid=(t[p].l+t[p].r)>>1;
if(mid>=l){
update(ls(p),l,r,k);
}
if(r>mid){
update(rs(p),l,r,k);
}
push_up(p);
}
inline int q(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r){
return t[p].pre;
}
push_down(p);
int mid=(t[p].l+t[p].r)>>1;
int ans=0;
if(mid>=l){
ans+=q(ls(p),l,r);
}
if(r>mid){
ans+=q(rs(p),l,r);
}
return ans;
}
inline int ask(int p,int bs,int res){
if(t[p].l==t[p].r){
return t[p].l;
}
push_down(p);
if(t[ls(p)].pre*bs>=res) return ask(ls(p),bs,res);
else return ask(rs(p),bs,res-t[ls(p)].pre*bs);
}
signed main(){
int n,m,w;
cin >> n >> m >> w;
int sum=0;
for(int i=1;i<=n;i++){
read(a[i]);
}
build(1,1,n);
while(m--){
int l,r,d;
read(l),read(r),read(d);
update(1,l,r,d);
int w1=w;
int bs=1;
int ans=0;
int sum=t[1].pre;
while(1){
if(w1>sum*bs){
w1-=sum*bs;
bs*=2;
ans++;
}else{
break;
}
}
cout << ans*n+ask(1,bs,w1)-1 << "\n";
}
return 0;
}