求助
查看原帖
求助
920320
bianshiyang楼主2024/11/23 23:01

P4597过来的,看到有大佬写整体二分,细想了思路很巧妙(先膜拜一下),又根据b数组的取值一定在a数组中,自己写了一版离散化的整体二分,在那道题是过了的

然鹅,搬到这道题发现喜提60分。大胆猜测是不是严格单调增后不满足b数组的值一定在a数组中出现,所以写挂了,于是写了一版不离散的整体二分,就过了。但是看了下题解,发现堆写法里面的元素都是a数组的值,所以问题不是出在这里,以为是long long的问题,结果全开了也没过,所以希望哪位大佬能看看蒟蒻的代码哪里有问题,十分感谢!

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+100;
typedef long long ll;
int n,a[N],a1[N],b[N];
ll ans;

void solve(int lv,int rv,int l,int r)
{
	if(l>r) return;
	if(lv==rv)
	{
		for(int i=l;i<=r;i++) b[i]=a1[lv];
		return;
	}
	int mid=(lv+rv)>>1;
	ll tot=0;
	for(int i=l;i<=r;i++) tot+=abs((ll)a[i]-a1[mid+1]);
	ll minn=tot;
	int k=l-1;
	for(int i=l;i<=r;i++)
	{
		tot-=abs((ll)a[i]-a1[mid+1]);tot+=abs((ll)a[i]-a1[mid]);
		if(tot<minn)
		{
			minn=tot;
			k=i;
		}
	}
	solve(lv,mid,l,k);solve(mid+1,rv,k+1,r);
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		a[i]-=i;
		a1[i]=a[i];
	}
	sort(a1+1,a1+n+1);
	solve(1,n,1,n);
	for(int i=1;i<=n;i++) ans+=abs((ll)a[i]-b[i]);
	printf("%lld\n",ans);
	for(int i=1;i<=n;i++) printf("%d ",b[i]+i);
	printf("\n");
	return 0;
}
2024/11/23 23:01
加载中...