感觉复杂度 O(nlogn+Qlogn+Qlog2n),但为啥跑不过去?常数大?
线段树代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
#define int long long
#define ls(x) x<<1
#define rs(x) x<<1|1
int n,q,W;
int a[N];
int w[N<<2],siz[N<<2],lzy[N<<2];
#define pushup(u) w[u]=w[ls(u)]+w[rs(u)]
void build(int u,int l,int r){
siz[u]=r-l+1;
if(l==r){
w[u]=a[l];
return;
}
int mid=l+r>>1;
build(ls(u),l,mid);
build(rs(u),mid+1,r);
pushup(u);
}
void pushdown(int u){
if(lzy[u]){
lzy[ls(u)]+=lzy[u];
lzy[rs(u)]+=lzy[u];
w[ls(u)]+=siz[ls(u)]*lzy[u];
w[rs(u)]+=siz[rs(u)]*lzy[u];
lzy[u]=0;
}
}
void modify(int u,int l,int r,int L,int R,int d){
if(L<=l&&r<=R){
w[u]+=siz[u]*d;
lzy[u]+=d;
}
else if(!(R<l||r<L)){
pushdown(u);
int mid=l+r>>1;
modify(ls(u),l,mid,L,R,d);
modify(rs(u),mid+1,r,L,R,d);
pushup(u);
}
}
int qry(int u,int l,int r,int L,int R){
if(L<=l&&r<=R){
return w[u];
}
if(!(R<l||r<L)){
pushdown(u);
int mid=l+r>>1;
return qry(ls(u),l,mid,L,R)+qry(rs(u),mid+1,r,L,R);
}
return 0;
}
int l,r,d;
signed main(){
// freopen("wxyt4.in","r",stdin);
// freopen("wxyt4.out","w",stdout);
cin.tie(0)->sync_with_stdio(0);
cin>>n>>q>>W;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
while(q--){
cin>>l>>r>>d;
modify(1,1,n,l,r,d);
int power=W,cnt=0;
while(power>0){
int sum=w[1];
if(power==sum){
cnt+=n-1; break;
}
if(power>sum){
power-=sum;
power/=2;
cnt+=n;
}
else{
int l=1,r=n,ans;
while(l<=r){
int mid=l+r>>1;
int ask=qry(1,1,n,1,mid);
if(ask==power){
ans=mid; break;
}
if(ask>power){
r=mid-1,ans=mid;
}
else{
l=mid+1;
}
}
cnt+=ans-1; break;
}
}
cout<<cnt<<"\n";
}
return 0;
}
另外问:树状数组能同时统计区间加和区间和吗?