社区讨论

#1~#7WA #8~#20TLE 求助玄关

P11217【MX-S4-T1】「yyOI R2」youyou 的垃圾桶参与者 2已保存回复 18

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
18 条
当前快照
1 份
快照标识符
@m2k6391q
此快照首次捕获于
2024/10/22 16:12
去年
此快照最后确认于
2025/11/04 23:48
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+10;
int w[N<<2],lzy[N<<2];//lzy处理子节点 
int n,q,W,a[N];
 void build(int i,int l,int r) {
	if(l==r) {
		w[i]=a[l];
		return ;
	}
	int mid=l+r>>1;
	build(i<<1,l,mid); build(i<<1|1,mid+1,r);
	w[i]=w[i<<1]+w[i<<1|1];//push_up处理父节点 
}
 void push_down(int i,int l,int r) {
	if(lzy[i]==0) return ;
	lzy[i<<1]+=lzy[i];
	lzy[i<<1|1]+=lzy[i];
	int mid=l+r>>1;
	w[i<<1]+=(mid-l+1)*lzy[i];
	w[i<<1|1]+=(r-mid)*lzy[i];
	lzy[i]=0;
}
 int find_sum(int i,int l,int r,int L,int R) {
	if(l==L&&r==R) return w[i];
	push_down(i,l,r);//!!!
	int mid=l+r>>1;
	if(R<=mid) return find_sum(i<<1,l,mid,L,R);
	else if(L>mid) return find_sum(i<<1|1,mid+1,r,L,R);
	else return find_sum(i<<1,l,mid,L,mid)+find_sum(i<<1|1,mid,r,mid+1,R);
}
 void update(int i,int l,int r,int L,int R,int c) {
	if(l==L&&r==R) {
		w[i]+=(r-l+1)*c; 
		lzy[i]+=c;
		return ;
	}
	push_down(i,l,r);
	int mid=l+r>>1;
	if(R<=mid) update(i<<1,l,mid,L,R,c); 
	else if(L>mid) update(i<<1|1,mid+1,r,L,R,c);
	else update(i<<1,l,mid,L,mid,c),update(i<<1|1,mid+1,r,mid+1,R,c);
	w[i]=w[i<<1]+w[i<<1|1];//处理父节点 
}
 int solve(int sum) {
	int cnt=0,m=W,x=sum;//cnt记录第几轮 
	int y=0;//记录二分前所消耗的生命值 
	while(m) {
		if(m-x<0) break;
		m-=x; y+=x; x*=2; 
		cnt++;
	}
	if(!m) return cnt*n-1;
	int l=1,r=n,ans=0;
	while(l<=r) {
		int mid=l+r>>1;
		int sum1=find_sum(1,1,n,1,mid)*(1ll<<cnt);
		if(sum1+y<W) {
			ans=mid; l=mid+1;
		}  
		else r=mid-1;
	}
	return cnt*n+ans;
} 
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin>>n>>q>>W;
	for(int i=1;i<=n;i++) 
	    cin>>a[i];
	build(1,1,n);
    while(q--) {
    	int l,r,d;
    	cin>>l>>r>>d;
    	update(1,1,n,l,r,d);
    	cout<<solve(find_sum(1,1,n,1,n))<<"\n";
	}
	return 0;
}
本人在写二分时借鉴了一下 temperature++!

回复

18 条回复,欢迎继续交流。

正在加载回复...