Examples

2022-7-28 #20 CF1329E

不知道为什么,最近总是在摆,好不容易 vp 一场也是随便糊弄。。。

只能说,😅😅😅。

「无论憧憬真挚与否 怜悯的缘由存在与否
沉谜底于心 笃信这缕光会为我指引」

054 CF1329E Dreamoon Loves AA

我们考虑一对 \((l,r)\) 需要满足的条件:

  • \(\forall 1\leqslant i\leqslant m,\lceil\frac nr\rceil\leqslant \lfloor\frac nl\rfloor\)
  • \(\sum_{i=1}^m\lceil\frac nr\rceil\leqslant m+k\leqslant \sum_{i=1}^m\lfloor\frac nl\rfloor\)

限制二可以拆开考虑,先二分出满足前面小于等于的最小 \(r\)(记作 \(r_0\)),以及满足后面小于等于的最大 \(l\)(记作 \(l_0\))。

\(l_0\geqslant r_0\),我们任选一对 \(l=r\),有 \(\sum_{i=1}^m\lceil\frac nr\rceil= \sum_{i=1}^m\lfloor\frac nl\rfloor\),可得 \(\lceil\frac nr\rceil= \lfloor\frac nl\rfloor\),满足条件。

否则,我们考虑调整 \(l_0,r_0\) 的取值使得满足限制一。

由于 \(l<r\),所以 $ \lfloor\frac nl\rfloor-\lceil\frac nr\rceil\geqslant -1$,我们需要将其调整到 \(0\),容易发现其会产生一个限制“\(l\leqslant L_k\)\(r\geqslant R_k\)”。

枚举左端点取值直接做就好了,复杂度 \(O(m\log m)\)

#include<stdio.h>
#include<algorithm>
#define int long long
#define inf 2000000000000000
using namespace std;
const int maxn=400005;
int T,n,k,m,l0,r0,ls,ans;
int p[maxn],q[maxn];
struct limit{
	int l,r;
}l[maxn];
inline int cmp(limit a,limit b){
	return a.l<b.l;
}
signed main(){
	scanf("%lld",&T);
	while(T--){
		scanf("%lld%lld%lld",&n,&m,&k),ls=0,ans=inf;
		for(int i=1;i<=m;i++)
			scanf("%lld",&p[i]);
		p[++m]=n;
		for(int i=1;i<=m;i++)
			q[i]=p[i]-p[i-1];
		int L=0,R=n+1;
		while(L+1<R){
			int mid=(L+R)>>1,sum=0;
			for(int i=1;i<=m;i++)
				sum+=q[i]/mid;
			if(sum>=m+k)
				L=mid;
			else R=mid;
		}
		l0=L;
		L=0,R=n+1;
		while(L+1<R){
			int mid=(L+R)>>1,sum=0;
			for(int i=1;i<=m;i++)
				sum+=(q[i]+mid-1)/mid;
			if(sum<=m+k)
				R=mid;
			else L=mid;
		}
		r0=R;
		if(l0>=r0){
			puts("0");
			continue;
		}
		for(int i=1;i<=m;i++){
			int L=(q[i]+r0-1)/r0,R=q[i]/l0;
			if(L>R)
				l[++ls]=limit{q[i]/L,R==0? inf:(q[i]+R-1)/R};
		}
		l[0]=limit{-inf,r0},l[++ls]=limit{l0,inf},sort(l+1,l+1+ls,cmp);
		int mx=-inf;
		for(int i=0;i<ls;i++)
			mx=max(mx,l[i].r),ans=min(ans,mx-l[i+1].l);
		printf("%lld\n",ans);
	}
	return 0;
}
posted @ 2022-07-28 23:12  xiaoziyao  阅读(43)  评论(0编辑  收藏  举报