(二分)P7405 [JOI 2021 Final] 雪玉 题解

思路

由于雪球之间的相对位置是不会改变的,所以对于一个雪球,越过相邻的雪球的初始位置一定不会令其变大。

如果雪球的滚动范围没有交集,答案显然就是区间长度。但如果有了交集,我们必须判断哪个雪球先滚到,一个区间便分为了分属左右两雪球的两个区间,于是就要找出两边最后一次不交的那个断点。

由于断点具有单调性,直接二分启动。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll maxn=2e5+5;
ll n,q;
ll a[maxn],w[maxn];
ll L[maxn],R[maxn],ans[maxn];
void solve(ll x,ll len) {
	if(L[q]+R[q]<=len) {
		ans[x]+=R[q];
		ans[x+1]+=L[q];
		return;
	}
	ll l=1,r=q;
	while(l<r) {
		ll mid=(l+r)/2;
		if(L[mid]+R[mid]>len)
			r=mid;
		else
			l=mid+1;
	}
	if(L[l]==L[l-1]) {
		ans[x]+=len-L[l];
		ans[x+1]+=L[l];
	} else {
		ans[x]+=R[l];
		ans[x+1]+=len-R[l];
	}
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>q;
	for(ll i=1; i<=n; i++)
		cin>>a[i];
	ll sum=0;
	for(ll i=1; i<=q; i++) {
		cin>>w[i];
		sum+=w[i];
		L[i]=max(L[i-1],-sum),R[i]=max(R[i-1],sum);
	}
	ans[1]+=L[q],ans[n]+=R[q];
	for(ll i=1; i<n; i++)
		solve(i,a[i+1]-a[i]);
	for(ll i=1; i<=n; i++)
		cout<<ans[i]<<endl;
	return 0;
}
posted @ 2024-02-20 09:49  p7gab  阅读(0)  评论(0编辑  收藏  举报  来源