二分前缀和 70pts 求助
  • 板块P9519 pay
  • 楼主Zelensky
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/9/9 21:00
  • 上次更新2023/11/2 21:47:22
查看原帖
二分前缀和 70pts 求助
649611
Zelensky楼主2023/9/9 21:00
#include<bits/stdc++.h>
#define int long long
const int maxn = 1e7+10000;
using namespace std;
int n,m;
int sum1[maxn],sum2[maxn],num1[maxn],num2[maxn],a[maxn],b[maxn];
bool vis[maxn];
bool check(int k)
{
	for(int i=1;i<=n;++i)
	{
		int ana = 0;
		int r = min(i+k,n);
		int ss = 1;
		int l = max(0ll,i-k);
		int x = sum1[i-1]-sum1[l-1];
		int y = sum2[i+1]-sum2[r+1];
		int xx = num1[i-1]-num1[l-1];
		int yy = num2[i+1]-num2[r+1];
		int s = (xx+yy)*k;
		x-=xx*sum1[l-1];
		y-=yy*sum2[r+1];
		xx = xx*(i-l);
		yy = yy*(r-i);
		x = xx-x;
		y = yy-y;
		s = s-x-y;
		if(vis[i]==1) s+=k;
		if(s<a[i]) return 0;
	}
	return 1;
}
 main()
{
	cin >> n >> m;
	int maxn = -1000000;
	for(int i=1;i<=n;++i) cin >> a[i],maxn = max(maxn,a[i]);
	for(int i=1;i<=m;++i)
	{
		cin >> b[i];
		vis[b[i]] = 1;
	}
	for(int i=1;i<=n;++i)
	{
		sum1[i]=sum1[i-1];
		num1[i]=num1[i-1];
		if(vis[i]==1)
		{
			sum1[i]+=i-1;
			num1[i]++;
		}
	}
	for(int i=n;i>=1;i--)
	{
		sum2[i]=sum2[i+1];
		num2[i]=num2[i+1];
		if(vis[i]==1)
		{
			sum2[i]+=n-i;
			num2[i]++;
		}
	}
	int l = 0,r = 1e12;
	int s=0;
	while(l<=r)
	{
		int mid = (l+r)/2;
		if(check(mid)) {
			r=mid-1;
			s = mid;
		}
		else l=mid+1;
	}
	cout << s;
}
2023/9/9 21:00
加载中...