首页 > 其他分享 >CF1329E Dreamoon Loves AA 题解

CF1329E Dreamoon Loves AA 题解

时间:2023-06-03 23:24:59浏览次数:38  
标签:AA lfloor lceil le frac 题解 rfloor Loves rceil

令 \(p_0=0,m\leftarrow m+1,p_{m}=n,a_i=p_i-p_{i-1}\),设在 \((p_{i-1},p_i)\) 中有 \(d_i-1\) 个 B 变成了 A,满足 \(\sum_{i=1}^m(d_i-1)=k\),让 \(k\leftarrow k+m\),这样 \(d\) 需要满足的限制就变成了 \(\sum_{i=1}^m d_i=k\)。这也可以看作把 \(a_i\) 分成 \(d_i\) 个正整数之和,每个正整数代表相邻两个 A 的距离,我们要最小化最后划分出来的正整数的极差。

可以发现每一段非负整数划分得越平均越好,所以每一段一定都是划分成若干个 \(\lfloor\frac{a_i}{d_i}\rfloor\) 和若干个 \(\lceil\frac{a_i}{d_i}\rceil\),我们要最小化的东西就是 \(\max_{i=1}^m\lceil\frac{a_i}{d_i}\rceil\le R-\min_{i=1}^m\lfloor\frac{a_i}{d_i}\rfloor\)。

现在给定 \((L,R)\),我们要判断是否存在 \(d_i\) 满足 \(\sum_{i=1}^m d_i=k,\max_{i=1}^m\lceil\frac{a_i}{d_i}\rceil\le R,\min_{i=1}^m\lfloor\frac{a_i}{d_i}\rfloor\ge L\),即每个被划分出的正整数都要在 \([L,R]\) 内,如果存在的话我们把 \(R-L\) 计入答案。注意 \(R-L\) 可能是大于此时的极差的,但这不会使最终答案变小,同时最优答案也一定会被统计到,所以不影响最终答案。

首先 \(d_i\ge\lfloor\frac{a_i}{L}\rfloor\),即记 \(t_L=\lfloor\frac{a_i}{L}\rfloor\),那么有 \(t_LL\le a_i,(t_L+1)L\gt a_i\),如果 \(t_LR\lt a_i\) 那就无解了,否则 \(t_LR\ge a_i\),由于 \(t_LL\le a_i\le t_LR\),所以我们可以把 \(a_i\) 分成 \(t_L\) 个 \([L,R]\) 内的正整数(且至多只能划分出 \(t_L\) 个)。

同理,通过 \(d_i\le\lceil\frac{a_i}{R}\rceil\) 也可以说明,记 \(t_R=\lceil\frac{a_i}{R}\rceil\),如果 \(t_RL>a_i\) 则无解,否则我们也一样可以把 \(a_i\) 分成 \(t_R\) 个 \([L,R]\) 内的正整数(且至少要划分出 \(t_R\) 个)。

由于 \(t_LL\le a_i\le t_LR\),\(t_RL\le a_i\le t_RR\),那么对于 \(t_R\le t\le t_L\) 也都有 \(tL\le a_i\le tR\),于是我们能且仅能把 \(a_i\) 分成 \(t\in[t_R,t_L]\) 个 \([L,R]\) 内的正整数。

我们再研究一下判有无解的式子,\(t_LR\ge a_i,t_RL\le a_i\),对于前者,代入 \(t_L=\lfloor\frac{a_i}{L}\rfloor\) 得 \(\lfloor\frac{a_i}{L}\rfloor R\ge a_i\Leftrightarrow \lfloor\frac{a_i}{L}\rfloor \ge\frac{a_i}{R}\Leftrightarrow \lfloor\frac{a_i}{L}\rfloor \ge \lceil\frac{a_i}{R}\rceil\),对于后者我们能推出同样的式子。

把 \(m\) 段综合一下,充要条件就是:1. \(\sum_{i=1}^m\lceil\frac{a_i}{R}\rceil\le k\le\sum_{i=1}^m\lfloor\frac{a_i}{L}\rfloor\);2. \(\forall 1\le i\le m,\lfloor\frac{a_i}{L}\rfloor \ge \lceil\frac{a_i}{R}\rceil\)。

对于第一个条件,\(L\) 有上限,\(R\) 有下限,可以二分求出 \(L\) 的上限 \(L_0\),\(R\) 的下限 \(R_0\),那么第一个条件成立当且仅当 \(L\le L_0\) 且 \(R\ge R_0\),所以答案至少为 \(R_0-L_0\)。

对于第二个条件,由于 \(L\le R\),所以 \(\frac{a_i}{L}\ge\frac{a_i}{R}\),那么不满足第二个条件时一定有 \(\lceil\frac{a_i}{R}\rceil=\lfloor\frac{a_i}{L}\rfloor+1\)。

如果没有不满足第二个条件的 \(a_i\),那么答案就是 \(R_0-L_0\)。

否则,我们希望通过调小 \(L\) 或调大 \(R\) 使得 \(\lfloor\frac{a_i}{L}\rfloor \ge \lceil\frac{a_i}{R}\rceil\) 成立,这等价于存在整数 \(x\),满足 \(\lfloor\frac{a_i}{L}\rfloor \ge x\ge \lceil\frac{a_i}{R}\rceil\),对于不等式前半部分 \(\lfloor\frac{a_i}{L}\rfloor \ge x\Leftrightarrow\frac{a_i}{L}\ge x\Leftrightarrow \frac{a_i}{x}\ge L\Leftrightarrow \lfloor\frac{a_i}{x}\rfloor\ge L\),不等式后半部分等价于 \(\lceil\frac{a_i}{x}\rceil\le R\),综合两式得到我们希望存在整数 \(x\) 使得 \(L\le\lfloor\frac{a_i}{x}\rfloor\le\lceil\frac{a_i}{x}\rceil\le R\)。

显然,我们希望 \(\lfloor\frac{a_i}{x}\rfloor\) 比 \(L\) 大且最接近 \(L\),或者 \(\lceil\frac{a_i}{x}\rceil\) 比 \(R\) 小且尽量接近 \(R\)。对于前者应让 \(x=\lfloor\frac{a_i}{L}\rfloor\),但由于现在不存在 \(x\) 满足上述条件,所以 \(\lceil\frac{a_i}{x}\rceil>R\),但我们发现 \(\lceil\frac{a_i}{x+1}\rceil\le R\),所以我们可以把 \(L\) 缩小到 \(\lfloor\frac{a_i}{x+1}\rfloor\);同理也可以把 \(R\) 扩大到 \(\lceil\frac{a_i}{\lceil\frac{a_i}{R}\rceil-1}\rceil\)。同时根据如上论述我们发现只需要把 \(L,R\) 其一缩小或扩大即可,而不需要同时改变两者。

也就是说,对于每个不满足条件的 \(a_i\),我们可以求出一个二元组 \((L_i,R_i)\),我们可以将 \(L\) 缩小为 \(L_i\),\(R\) 不变,或者将 \(R\) 扩大为 \(R_i\),\(L\) 不变。现在你有很多对二元组,你要在每个二元组中选一个元素,并修改对应的 \(L,R\),希望最终得到的 \(R-L\) 最小。这是一个很经典的问题,做法是把二元组按第一维排序,容易证明选 \(L_i\) 的二元组一定是一段后缀。

总时间复杂度 \(O(m\log n)\)。

Code

#include<bits/stdc++.h>
#define LL long long
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const int MxN=400002;
LL n,k,l,r,mid,res,L,R,ans;
int m,Test_num;
LL a[MxN];
typedef pair<LL,LL> P;
vector<P> vec;
template<class T>void read(T &x)
{
	x=0;int f=0;char ch=getchar();
	while(ch<'0' || ch>'9')f|=(ch=='-'),ch=getchar();
	while(ch>='0' && ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	x=f? -x:x;return ;
}
inline void solve()
{
	read(n),read(m),read(k),vec.clear(),ans=inf;
	for(int i=1;i<=m;++i)read(a[i]);
	a[0]=0,a[++m]=n,k+=m;
	for(int i=m;i;--i)a[i]-=a[i-1];
	for(l=1,r=n;l<=r;)
	{
		mid=((l+r)>>1),res=0;
		for(int i=1;i<=m;++i)res+=(a[i]+mid-1)/mid;
		if(res<=k)r=mid-1;
		else l=mid+1;
	}
	R=l;
	for(l=1,r=n;l<=r;)
	{
		mid=((l+r)>>1),res=0;
		for(int i=1;i<=m;++i)res+=a[i]/mid;
		if(res>=k)l=mid+1;
		else r=mid-1;
	}
	L=r;
	for(int i=1;i<=m;++i)
	{
		LL x=a[i]/L,y=(a[i]+R-1)/R;
		if(x<y)vec.push_back(P(a[i]/(x+1),y>1? (a[i]+y-2)/(y-1):inf));
	}
	if(!vec.size())return (void)(printf("%lld\n",R-L));
	sort(vec.begin(),vec.end()),res=-inf;
	for(int i=0;i<vec.size();++i)ans=min(ans,max(R,res)-min(L,vec[i].first)),res=max(res,vec[i].second);
	ans=min(ans,max(R,res)-L),printf("%lld\n",ans);
}
int main()
{
	for(read(Test_num);Test_num--;)solve();
	return 0;
}

标签:AA,lfloor,lceil,le,frac,题解,rfloor,Loves,rceil
From: https://www.cnblogs.com/18Michael/p/17454977.html

相关文章

  • ABC302Ex Ball Collector 题解
    注意到当有那些\((a_i,b_i)\)是确定的时,答案就是将\((a_i,b_i)\)连边后每个连通块的\(\min(|V|,|E|)\)之和。那么这个东西用可撤销并查集维护即可。#include<algorithm>#include<cstdio>usingnamespacestd;constintN=2e5;structEdge{intto,nxt;}e[......
  • 2023青岛市程序设计竞赛小学组题解
    1.付钱题目链接:https://www.luogu.com.cn/problem/U303904代码:#include<bits/stdc++.h>#definelllonglongusingnamespacestd;intmain(){ lln;cin>>n; cout<<n/100<<''<<(n%100)/50<<''<<(n%50)/20......
  • 第十届蓝桥杯c++b组国赛题解(还在持续更新中...)
    试题A:平方序列解题思路:直接枚举一遍x的取值,然后按照题目给定的式子算出y,每次取x+y的最小值即可答案为7020代码实现:#include<iostream>#include<algorithm>#include<cmath>usingnamespacestd;#defineintlonglongconstintN=1e4+5;signedmain(){ //记录答案......
  • ABC215E 题解
    前言题目传送门!更好的阅读体验?萌萌DP题。思路题目就是在说从\(a\)里面按顺序掏出来一些字母,使得相同的字母都是相邻的(比如AABBBBCD可行,AAABBCAA不行)。看起来很不可做,突破口在于\(\text{A}\sim\text{J}\)一共只有\(10\)个字母,考虑状压。设\(dp_{i,s}\)表示......
  • 「解题报告」CF1329E Dreamoon Loves AA
    好题。首先可以把题意转化一下,我们先把每相邻两个A的距离写成一个数组,然后对这个数组进行考虑。那么我们每改一个数,实际上就是将这个数组中的一个数分成两个数,我们要求的就是把这个数组分成\(K=k+m+1\)个数,最小化极差。首先不难得出一点,就是每个数最后肯定是被均分成......
  • 道路翻修题解
    \(\mathcal{Description}\)给定一张无向图,为每条边定向,定义每个点的价值为出度与入度之差的绝对值,求最大价值和。对于\(40\%\)的数据,\(1\leqn,m\leq20\)。对于\(70\%\)的数据,\(1\leqn\leq17\)。对于\(90\%\)的数据,\(1\leqn\leq22\)。对于所有数据,\(1\leqn\leq25\)......
  • CF1808E3 题解
    题意传送门求有多少包含\(n\)位数码的\(k\)进制数,满足存在一位数等于其他\(n-1\)位数的总和模\(k\)。\(1\len\le10^{18},1\lek\le2000\)。题解简单的组合数学都不会了……蔬菜越来越多,我该怎么办?条件等价于存在某一位\(x\),满足\(2x\equivs\pmodk\)。容易想到......
  • P1545 [USACO04DEC] Dividing the Path G 题解
    丢一发好理解又好写的线段树优化dp。题目传送门简要题意给定一个长为\(l\)的线段,求出尽量少的不相交区间覆盖整段线段,要求题目给的所有子区间只被\(1\)个区间覆盖。分析显然题目给的子区间\([s,e]\)中只有\(s\)和\(e\)端点能作为线段端点,所以我们应该给\([s+1,......
  • 【Pytorch】ValueError: not enough values to unpack (expected 2, got 1)问题解决
    在运行开源项目时出现了这个问题,网上很多说删回车或者都改成英文符号,但是我都试了,没用后来自己摸索出的方法是:先更改数据集的格式,之前分隔符是\t,把数据集中的分隔符改成空格,再把语句中的\t也换成空格,然后就不会报错了。改前:改后:......
  • python pip安装库时遇到fatal error的问题解决
    当时的图片没有留,写点东西做备忘吧。一开始尝试pipinstallxx库,cmd提示pip不是批处理文件或命令,解决方法:去属性的高级设置里,在用户变量的Path里增加pip所在的路径,如果不知道pip在哪里,就在cmd里输入wherepip查询,查不到就在文件管理里用查询。解决这个问题后,再尝试安装,错误提示......