• 2022728 #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;
    }
    
  • 相关阅读:
    字典与集合
    gitee
    在使用pycharm时同时缩进、左移、多行注释
    代码1(while循环和IF条件语句,字符格式化,break,continue)
    python基础-工具
    11 Serializer组件
    10 响应模块
    09 异常模块
    08 解析模块
    07 渲染模块
  • 原文地址:https://www.cnblogs.com/xiaoziyao/p/16530595.html
Copyright © 2020-2023  润新知