80pts TLE 二分线段树求调
查看原帖
80pts TLE 二分线段树求调
388602
CA_FZZSL楼主2024/10/21 16:09
#include<bits/stdc++.h>
#define MAXN 2000010
#define int long long
using namespace std;

inline void read(int &a){
	bool w = false; a = 0;
	char c = getchar();
	while(c>'9'||c<'0'){if(c=='-')w=true;c=getchar();}
	while(c>='0'&&c<='9'){a=(a<<3)+(a<<1)+(c^48);c=getchar();}
	if(w) a = -a;
}
int n,q,w;
int a[MAXN];
int seg[MAXN],pls[MAXN];

inline void pushup(int rt){
	seg[rt] = seg[rt<<1] + seg[rt<<1|1];
}

inline void pushdown(int rt,int l,int r){
	if(!pls[rt]) return;
	pls[rt<<1] += pls[rt];
	pls[rt<<1|1] += pls[rt];
	int mid = (l+r)>>1;
	seg[rt<<1] += pls[rt] * (mid-l+1);
	seg[rt<<1|1] += pls[rt] * (r-mid);
	pls[rt] = 0;
} 

void build(int rt,int l,int r){
	if(l==r){
		seg[rt] = a[l];
		return;
	}
	int mid = (l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	pushup(rt);
}

void update(int rt,int l,int r,int x,int y,int p){
	if(x<=l&&y>=r){
		seg[rt] += p * (r-l+1);
		pls[rt] += p;
		return;
	}
	pushdown(rt,l,r);
	int mid = (l+r)>>1;
	if(x<=mid) update(rt<<1,l,mid,x,y,p);
	if(y>mid) update(rt<<1|1,mid+1,r,x,y,p);
	pushup(rt);
}

int quary(int rt,int l,int r,int per,int m){
	if(l == r) return 1;
	pushdown(rt,l,r);
	int mid = (l+r)>>1;
	if(seg[rt<<1] * per < m) return (mid-l+1)+quary(rt<<1|1,mid+1,r,per,m-per*seg[rt<<1]);
	return quary(rt<<1,l,mid,per,m);
}

signed main(){
	
	read(n);
	read(q);
	read(w);
	for(int i=1;i<=n;i++) read(a[i]);
	build(1,1,n);
	int l,r,d;
	for(int i=1;i<=q;i++){
		read(l);
		read(r);
		read(d);
		update(1,1,n,l,r,d);
		int k = seg[1],locnt = 0,ans = 0;
		int now = w;
		while(now>k*(1<<locnt)){
			now -= k*(1<<locnt);
			locnt++;
			ans += n;
		}
		printf("%lld\n",ans+quary(1,1,n,(1<<locnt),now)-1);
	}
	return 0;
} 
2024/10/21 16:09
加载中...