P8049 题解
Dream__Sky · · 题解
本题弱化版
弱化版可用二分答案的算法来求解,但是这题的数据就不支持
考虑尺取法。
以下定义
普通暴力为,从
最后,可能有一些点还没有被更新答案,那我们考虑当前这一位与前一位的关系。考虑不取前一位,为了还满足是
如何从暴力上优化?这就要提到尺取法了。当我们变动
在尺取过程中,可以使用前缀和来快速计算区间和。当然也可以边尺取,边计算连续一段区间的和。
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,s,a[100010],t[100010],c[100010];
signed main()
{
cin>>n>>s;
for(int i=1;i<=n;i++) cin>>a[i],c[i]=c[i-1]+a[i];//前缀和
int l=1,r=1;
for(int i=1;i<=n;i++)//i即为mid
{
while(c[i]-c[l-1]>s) l++;//左端点移动
while(c[r+1]-c[i]<=s&&r<n) r++;//右端点移动
int K=min(i-l+1,r-i);//计算K
t[i-K+1]=K*2;//记录长度
}
for(int i=1;i<=n;i++) t[i]=max(t[i-1]-2,t[i]);//记录未被记录长度的点的长度(有点绕?
for(int i=1;i<=n;i++) cout<<t[i]<<"\n";
return 0;
}