刚刚结束的 D 求调
  • 板块学术版
  • 楼主w9095
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/1/22 22:08
  • 上次更新2025/1/23 09:59:17
查看原帖
刚刚结束的 D 求调
569235
w9095楼主2025/1/22 22:08

思路是三分

#include <bits/stdc++.h>
using namespace std;
long long t,n,m,a[300000],b[300000],pa[300000],pb[300000],ou[300000];
long long check(long long x,long long k)
{
	if(x>k||x<0)return -1e18;
	if((x*2+k-x)>n||(x+(k-x)*2)>m||pa[x]==-1e18||pb[k-x]==-1e18)return -1e18;
	return max(pa[x]+pb[k-x],-(long long)1e18);
}

int main()
{
	scanf("%lld",&t);
	while(t--)
	   {
	   	scanf("%lld%lld",&n,&m);
	   	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
	   	for(int i=1;i<=m;i++)scanf("%lld",&b[i]);
	   	sort(a+1,a+n+1),sort(b+1,b+m+1);
	   	for(int i=1;i<=m+n;i++)pa[i]=pb[i]=-1e18;
	   	for(int i=1;i<n-i+1;i++)
		    if(a[n-i+1]!=a[i])pa[i]=pa[i-1]+a[n-i+1]-a[i];
		    else break;
	   	for(int i=1;i<m-i+1;i++)
		    if(b[m-i+1]!=b[i])pb[i]=pb[i-1]+b[m-i+1]-b[i];
		    else break;
		long long flag=0;
	   	for(int i=1;i<=1000000;i++)
	   	    {
	   	    long long l=0,r=i,ans=-1e18;
	   	    while(l<=r)
	   	       {
	   	       long long lmid=(l*2+r)/3,rmid=(l+r*2)/3;
			   if(check(lmid,i)>=check(rmid,i))ans=max(ans,check(lmid,i)),r=rmid-1;
			   else ans=max(ans,check(rmid,i)),l=lmid+1;
			   }
			ans=max(ans,check(l,i)),ans=max(ans,check(r,i)),l=0,r=i;
	   	    while(l<=r)
	   	       {
	   	       long long lmid=(l*2+r)/3,rmid=(l+r*2)/3;
			   if(check(lmid,i)>check(rmid,i))ans=max(ans,check(lmid,i)),r=rmid-1;
			   else ans=max(ans,check(rmid,i)),l=lmid+1;
			   }
			ans=max(ans,check(l,i)),ans=max(ans,check(r,i)),ou[i]=ans;
			if(ou[i]==-1e18)
			   {
			   	printf("%d\n",i-1),flag=i-1;
			   	for(int j=1;j<=i-1;j++)printf("%lld ",ou[j]);
			   	break;
			   }
			}
		if(flag)printf("\n");
	   }
	return 0;
}
2025/1/22 22:08
加载中...