线性前缀和做法,90PtsWA两个个点,大佬求调
  • 板块P9519 pay
  • 楼主huangyuxaing
  • 当前回复5
  • 已保存回复5
  • 发布时间2023/8/12 20:49
  • 上次更新2023/11/3 04:12:23
查看原帖
线性前缀和做法,90PtsWA两个个点,大佬求调
591179
huangyuxaing楼主2023/8/12 20:49
#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int M=1e6+7;
int n,m,a[M],v[M],b[M],ll[M],rr[M],cnt[M];
bool flag[M];
bool check(int x){
	for(int i=1;i<=n;i++)cnt[i]=0LL;
	for(int i=1;i<=n;i++)ll[i]=0LL;
	for(int i=1;i<=n;i++){
		cnt[i]=cnt[i-1]-(int)(flag[max(0LL,i-x)]);
		ll[i]=ll[i-1]-cnt[i]+(int)(flag[i])*x;
		cnt[i]+=(int)(flag[i]);
	}
	for(int i=1;i<=n;i++)cnt[i]=0LL;
	for(int i=1;i<=n;i++)rr[i]=0LL;
	for(int i=n;i>=1;i--){
		cnt[i]=cnt[i+1]-(int)(flag[min(n+1,i+x)]);
		rr[i]=rr[i+1]-cnt[i]+(int)(flag[i])*x;
		cnt[i]+=(int)(flag[i]);
	}
	for(int i=1;i<=n;i++){
		v[i]=ll[i]+rr[i]-(int)(flag[i])*x;
		//if(x==18)cout<<v[i]<<" ";
		if(v[i]<a[i])return false;
	}
	//cout<<endl;
	return true;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	for(int i=1;i<=m;i++){
		scanf("%lld",&b[i]);
		flag[b[i]]=true;
	}
	int l=0,r=1e12;
	//cout<<check(18)<<endl;
	while(l<=r){
		for(int i=1;i<=n;i++)v[i]=0LL;
		int mid=(l+r)>>1;
		if(check(mid))r=mid-1;
		else l=mid+1;
	}
	cout<<l<<endl;
	return 0;
}
2023/8/12 20:49
加载中...