CodeForces - 626E 三分

本文解析了一道算法题,题目要求从给定的整数集中选取若干个数,使得所选数的平均值与中位数之差最大化。文章详细介绍了如何通过三分法和二分法寻找最优解,并提供了AC代码。
部署运行你感兴趣的模型镜像

题意:给n个数,从这n个数里,任意选一些数,使得这些数的平均值减去中位数尽可能的大

精度卡的好恶心啊。。。。。

首先发现集合个数一定是奇数,任何一个个数为偶数的集合,都可以通过去掉中间较大的那个数,来增大或不变这个值

如1 2 3 4 可以去掉3变成1 2 4

排序后,枚举每个数做中位数,然后三分集合个数

确定中位数之后,剩下的数肯定是越大越好,

会发现这个值并不是随着集合个数单调变化的,所以要三分求凸点。

直接double除法,会有精度问题,可以转换成乘法比较

换了好几种三分形式,都不对。。。。各种怀疑。。。。并不是很理解。。

ac代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
int a[maxn], n;
long long s[maxn];
long long fun(int x, int cnt){
	int l = x - cnt;
	int r = n - cnt + 1;
	long long sum = s[n] - s[r - 1] + s[x] - s[l - 1];
	return sum - 1ll * (2 * cnt + 1) * a[x];
}
int main(){
	cin >> n;
	for(int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
	}
	sort(a + 1, a + n + 1);
	if(n <= 2){
		cout << 1 << endl;
		cout << a[1] << endl;
		return 0;
	}
	for(int i = 1; i <= n; i++){
		s[i] = s[i - 1] + a[i];
	}
	long long minn = 0, ans_index = 1, ans_count = 0;
	for(int i = 2; i < n; i++){
		int le = 1, ri = min(i - 1, n - i);
		long long minn_now = 0, ans = 0;
		while(le <= ri){
			int mid1 = (le + ri) >> 1;
			int mid2 = (ri + 1 + mid1) >> 1;
			long long f1 = fun(i, mid1);
			long long f2 = fun(i, mid2);
			if(f1 * (2 * mid2 + 1) < f2 * (2 * mid1 + 1)){
				le = mid1 + 1;
			}
			else{
				ri = mid2 - 1;
			}
		}
		ans = le, minn_now = fun(i, le); 
	//	cout << i << " " << ans << endl;
		if(minn_now * (2 * ans_count + 1) > minn * (2 * ans + 1)){
			ans_index = i;
			ans_count = ans;
			minn = minn_now;
		} 
	}
	cout << ans_count * 2 + 1 << endl;
	for(int i = ans_index - ans_count; i <= ans_index; i++)
	cout << a[i] << " ";
	for(int i = n - ans_count + 1; i <= n; i++)
	cout << a[i] << " ";
	cout << endl;
	return 0;
} 

wa的代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
int a[maxn], n;
long long s[maxn];
long long fun(int x, int cnt){
	int l = x - cnt;
	int r = n - cnt + 1;
	long long sum = s[n] - s[r - 1] + s[x] - s[l - 1];
	return sum - 1ll * (2 * cnt + 1) * a[x];
}
int main(){
	cin >> n;
	for(int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
	}
	sort(a + 1, a + n + 1);
	if(n <= 2){
		cout << 1 << endl;
		cout << a[1] << endl;
		return 0;
	}
	for(int i = 1; i <= n; i++){
		s[i] = s[i - 1] + a[i];
	}
	long long minn = 0, ans_index = 1, ans_count = 0;
	for(int i = 2; i < n; i++){
		int le = 1, ri = min(i - 1, n - i);
		long long minn_now = 0, ans = 0;
		while(le < ri){
			int mid1 = (2 * le + ri) / 3;
			int mid2 = (le + 2 * ri) / 3;
			long long f1 = fun(i, mid1);
			long long f2 = fun(i, mid2);
			if(f1 * (2 * mid2 + 1) <= f2 * (2 * mid1 + 1)){
				le = mid1 + 1;
			}
			else{
				ri = mid2 - 1;
			}
		}
		ans = le, minn_now = fun(i, le); 
		if(minn_now * (2 * ans_count + 1) > minn * (2 * ans + 1)){
			ans_index = i;
			ans_count = ans;
			minn = minn_now;
		} 
	}
	cout << ans_count * 2 + 1 << endl;
	for(int i = ans_index - ans_count; i <= ans_index; i++)
	cout << a[i] << " ";
	for(int i = n - ans_count + 1; i <= n; i++)
	cout << a[i] << " ";
	cout << endl;
	return 0;
} 

也可以二分来做,比较一下mid+1和mid-1就可以了




您可能感兴趣的与本文相关的镜像

Yolo-v8.3

Yolo-v8.3

Yolo

YOLO(You Only Look Once)是一种流行的物体检测和图像分割模型,由华盛顿大学的Joseph Redmon 和Ali Farhadi 开发。 YOLO 于2015 年推出,因其高速和高精度而广受欢迎

<think> 根据用户需求,需要提供Codeforces 1617B题目的解题方案。首先,我需要回忆或查找该题目的内容。题目编号1617B对应的是Codeforces Round #767 (Div. 2)的B题,题目名称为"GCD Problem"。 题目描述大致如下:给定一个正整数$n$($n \geq 10$),要求找到三个互不相同的正整数$a$, $b$, $c$,满足以下条件: 1. $a + b + c = n$ 2. $\gcd(a, b) = c$ 注意:$a$, $b$, $c$必须是互不相同的正整数。 解题思路: 1. 由于$c$是$a$和$b$的最大公约数,我们可以设$a = c \cdot d$,$b = c \cdot e$,其中$d$和$e$是互质的整数(即$\gcd(d,e)=1$)。 2. 那么,$a + b + c = c \cdot d + c \cdot e + c = c \cdot (d + e + 1) = n$。 3. 因此,$c$必须是$n$的一个因子。但直接枚举因子可能比较复杂,我们可以尝试构造。 4. 注意到题目要求$a$、$b$、c互不相同,且$c=\gcd(a,b)$,我们可以尝试固定$c=1$,那么问题转化为:找到两个互质的正整数$d$和$e$,使得$d+e+1 = n$(因为$c=1$),即$d+e = n-1$,且$a=d, b=e, c=1$,同时要保证$a,b,c$互不相同。 5. 但是,如果$c=1$,那么$d$和$e$需要满足$d+e=n-1$且$\gcd(d,e)=1$。我们可以选择$d=1$,那么$e=n-2$,此时$\gcd(1, n-2)=1$,所以$a=1, b=n-2, c=1$。但是这里$a=1$和$c=1$相同,违反了互不相同的条件。 6. 因此,我们需要调整。我们可以取$c$为一个不等于1的数?但是题目要求互不相同,同时$c$是$a$和$b$的公约数,而且$c$应该小于$a$和$b$。我们可以尝试取$c$为$n$的某个真因子,但这样可能复杂。 另一种思路: - 由于$n$比较大($n \geq 10$),我们可以尝试令$c$为一个较小的数,比如$c=1$,然后寻找两个互质的数$d$和$e$,使得$d+e=n-1$,且$d,e \geq 2$(这样保证$a,b,c$互不相同)。 - 因为$d$和$e$互质,且$d+e=n-1$,那么我们可以取$d=2$,那么$e=n-3$,此时需要满足$\gcd(2, n-3)=1$。如果$n-3$是奇数,那么$\gcd(2, n-3)=1$(因为2和任何奇数互质)。那么,当$n$是偶数时,$n-3$是奇数吗?注意$n$是偶数时,$n-3$是奇数,所以成立;当$n$是奇数时,$n-3$是偶数,那么$\gcd(2, n-3)=2$(如果$n-3$是偶数),所以不互质。因此,当$n$为奇数时,不能取$d=2$。 改进: - 我们可以取$d$和$e$为两个相邻的数?因为相邻的数互质。设$d$和$e$为两个相邻的正整数,那么$d$和$e$互质,且$d+e=k$(这里$k=n-1$)。那么我们可以取$d = \lfloor k/2 \rfloor$,$e = \lceil k/2 \rceil$,但是要注意相邻的两个整数互质,但这里$d$和$e$不一定相邻,而是和为$k$的两个相邻整数?实际上,任意两个相邻整数互质,所以我们只需要找到两个相邻的整数,使得它们的和为$n-1$?显然,$n-1$是奇数时,可以拆成两个相邻整数(一奇一偶)且互质。但$n-1$为偶数时,相邻整数只能是一奇一偶,但$n-1$为偶数时,两个相邻整数的和是奇数,矛盾?所以当$n-1$是偶数时,我们无法拆成两个相邻整数。 重新考虑:我们只需要两个互质的数,不一定相邻。当$n$为奇数时,我们可以这样构造: 令 $c=1$,则 $d+e = n-1$,且$d,e$互质。我们可以取$d=2$,那么$e=n-3$,但是$n$是奇数,$n-3$是偶数,所以$\gcd(2, n-3)=2$(除非$n-3=2$,即$n=5$,但$n>=10$,所以不行)。那么取$d=3$,$e=n-4$,此时需要$\gcd(3, n-4)=1$。由于$n$是奇数,$n-4$也是奇数,所以不一定互质,但我们可以尝试。 实际上,我们可以取$d$为小于$n-1$的一个较小的数,使得$d$和$e=n-1-d$互质。因为$n-1$是偶数(当$n$为奇数时,$n-1$为偶数),那么我们可以取$d$为奇数?因为两个奇数的和是偶数,而$n-1$是偶数,所以我们可以取两个奇数?但是两个奇数不一定互质。 有一个简单的构造方法: 令 $c=1$,则我们需要将$n-1$拆成两个互质的数$d$和$e$,且$d,e \geq 2$(这样$a,b$至少为2,而$c=1$,所以三者互不相同)。那么,我们可以取$d=2$,$e=n-3$,然后检查$\gcd(2, n-3)$是否为1。当$n$为偶数时,$n-3$是奇数,所以$\gcd(2, n-3)=1$,成立。当$n$为奇数时,$n-3$是偶数,所以$\gcd(2, n-3) \geq 2$,不成立。因此,当$n$是奇数时,我们可以取$d=3$,那么$e=n-4$,此时$n-4$是奇数(因为$n$是奇数,减4还是奇数),那么$\gcd(3, n-4)$可能等于1也可能大于1。但是,由于$n$足够大($n \geq 10$),我们可以确保存在一个较小的$d$使得$d$和$n-1-d$互质。 实际上,我们可以取$d$为小于$n-1$的质数,那么只要$n-1-d$不是$d$的倍数,就互质?但这样不一定,因为互质要求没有共同的质因子。 更简单的构造:取$d$为大于1的奇数,且$d$和$n-1-d$互质。由于$n-1$是偶数(当$n$为奇数时),那么$d$和$n-1-d$都是奇数,且它们相差$2d-(n-1)$?我们可以取$d$为3,然后检查$n-4$是否是3的倍数?如果不是,则$\gcd(3, n-4)=1$。如果是3的倍数,那么我们可以尝试$d=5$,直到找到一个$d$使得$d$和$n-1-d$互质。由于$n-1$是偶数,而$d$是奇数,$n-1-d$也是奇数,所以只要$d$和$n-1-d$没有共同的质因子即可。 但是,题目要求$d$和$e$互质,且$d,e \geq 2$,我们可以固定$d=2$或$d=3$?实际上,我们可以这样: 当$n$是偶数时,取$a=2, b=n-3, c=1$(因为$n$是偶数,$n-3$是奇数,所以$gcd(2, n-3)=1$)。 当$n$是奇数时,取$a=3, b=n-4, c=1$,然后检查$n-4$是否是3的倍数?如果是,那么我们需要调整,比如取$d=4$?但是$d=4$和$e=n-5$不一定互质。实际上,我们可以避免检查:取$d$和$e$分别为$(n-1)/2-1$和$(n-1)/2+1$?这样它们都是奇数,且相邻(差2),那么它们的最大公约数可能是2?但是相邻奇数互质?不对,相邻奇数是指相差2,它们不一定互质(例如15和25,相差10,但可以互质?但15和25不互质)。相邻奇数(相差2)不一定互质,例如9和15,相差6,但都有因子3。 实际上,我们可以这样:因为$n$是奇数,所以$n-1$是偶数。那么我们可以取$d$为2,$e$为$n-3$,但是$n-3$是偶数,所以不互质。那我们取$d$为1?不行,因为$a=c\cdot d$,如果$d=1$,那么$a=c$,但$c=1$,则$a=1$,与$c$相同,而且$b$会等于$n-2$,那么$c=1$,$a=1$,$b=n-2$,这样$a$和$c$重复。 因此,我们改变思路:不固定$c=1$。我们可以取$c$为其他值。 另一种常见的构造: 取$c$为$n$的因子,且$c$较小。例如,我们可以取$c$为$n$除以2的某个因子?但题目要求$c=\gcd(a,b)$,且$a,b,c$互不相同。 观察题目样例:$n=10$,输出$1,2,7$?不对,因为$1+2+7=10$,但$\gcd(1,2)=1$,所以$c=1$,即$a=1,b=2,c=1$?这里$a$和$c$相同,不符合。实际上,题目样例的答案是:$n=10$,输出$3,5,2$,因为$3+5+2=10$,且$\gcd(3,5)=1$?不对,应该是$\gcd(3,5)=1$,而$c=2$?不对,因为$\gcd(3,5)=1$,不等于2。所以重新检查题目。 实际上,题目1617B的样例:输入10,输出4 5 1(因为4+5+1=10,且gcd(4,5)=1,而c=1,满足条件)。但是题目要求$\gcd(a,b)=c$,这里$\gcd(4,5)=1$,所以c=1,满足。 所以正确的构造是:令$c=1$,然后取$a$和$b$为两个互质的数,且$a+b=n-1$,并且$a,b \geq 2$,且$a,b$互不相同。 那么,对于任意$n \geq 10$,我们如何快速找到两个互质的数$a,b$满足$a+b=n-1$且$a,b \geq 2$? - 当$n$是偶数时,$n-1$是奇数,那么我们可以取$a=2$,$b=n-3$(因为$n$是偶数,$n-3$是奇数,所以$a$是偶数,$b$是奇数,且$\gcd(2, n-3)=1$,因为$n-3$是奇数)。 - 当$n$是奇数时,$n-1$是偶数,那么我们可以取$a=3$,$b=n-4$($n$是奇数,$n-4$也是奇数),那么$\gcd(3, n-4)$是否等于1?不一定,比如当$n-4$是3的倍数时,$\gcd(3, n-4)\ge3$。例如$n=13$,$n-4=9$,$\gcd(3,9)=3$,不满足。所以我们需要调整。 对于$n$是奇数的情况,我们可以取$a$为大于1的奇数,且与$b=n-1-a$互质。因为$n-1$是偶数,所以$a$和$b$都是奇数。我们可以从3开始,每次增加2(即取3,5,7,...),直到找到一个$a$使得$\gcd(a, b)=1$。由于$n$比较大($n\ge10$),且$n-1$是偶数,所以$b=n-1-a$也是奇数,且随着$a$增大,$b$减小。由于连续的两个奇数互质?不一定,但我们可以保证在较小的范围内找到。实际上,我们可以取$a$为一个小于$n-1$的质数,那么只要$b$不是这个质数的倍数,就互质。但是$b$可能是这个质数的倍数,所以我们不能保证。 另一种思路:我们取$a$为$(n-1)/2$附近的数。例如,取$a = (n-1)/2 - t$,$b = (n-1)/2 + t$,其中$t$为正整数。那么$a$和$b$都是整数,且关于$(n-1)/2$对称。我们需要$\gcd(a,b)=1$。由于$a$和$b$都是奇数(因为$n-1$是偶数,所以$(n-1)/2$是整数),且它们的差是$2t$,所以它们同奇偶(都是奇数)。而两个奇数互质的概率较大。实际上,我们可以取$t=1$,则$a=(n-1)/2-1$,$b=(n-1)/2+1$,那么有$\gcd(a,b)=\gcd(a, a+2)$(因为$b=a+2$),而$\gcd(a, a+2)=\gcd(a,2)$。由于$a$是奇数(因为$n-1$是偶数,$(n-1)/2$是整数,那么$a$和$b$都是整数,且$a$是奇数,因为$(n-1)/2$是整数,减去1还是整数,而$n$是奇数,$n-1$是偶数,所以$(n-1)/2$是整数,且$a=(n-1)/2-1$是奇数?因为$(n-1)/2$是整数,而$n-1$是偶数,所以$(n-1)/2$可能是奇数也可能是偶数。但$a$和$b$都是整数,且$b=a+2$。$\gcd(a, a+2)=\gcd(a,2)$,因为$a$是奇数(因为$n$是奇数,$n-1$是偶数,而$a=(n-1)/2-1$,由于$(n-1)/2$是整数,而$n-1$是偶数,所以$(n-1)/2$的奇偶性取决于$n$。例如$n=11$,$n-1=10$,$(n-1)/2=5$,则$a=5-1=4$,$b=5+1=6$,但4和6都是偶数,且$\gcd(4,6)=2$。所以不成立。 因此,我们需要更直接的构造。实际上,我们可以取$c$为$n$的一个真因子,但这样构造复杂。我们再看题目,题目要求三个互不相同的正整数,且$c=\gcd(a,b)$,那么$c$一定小于等于$a$和$b$,且$c$至少为1。 实际上,我们可以取$c$为2?那么$a$和$b$都是2的倍数,且$a+b=n-2$。那么我们可以设$a=2, b=n-4$,那么$c=2$,则$a=2, b=n-4, c=2$,这样$a$和$c$相同,不行。所以我们需要$a$和$b$大于2,且是2的倍数,且互质?但两个大于2的偶数不可能互质(因为它们都有因子2)。所以取$c=2$也不行。 我们取$c=3$?那么$a$和$b$都是3的倍数,设$a=3, b=3k$,则$a+b+c=3+3k+3=3(k+2)=n$,所以$n$必须是3的倍数。但$n$不一定是3的倍数,所以不行。 因此,我们回到$c=1$。对于$n$为奇数的情况,我们取$a$和$b$为两个奇数,且和为$n-1$,且互质。我们可以取$a=3$,$b=n-4$,如果$\gcd(3, n-4)=1$,则成立;否则,取$a=5$,$b=n-6$,如果$\gcd(5, n-6)=1$,则成立;以此类推。由于$n$是固定的,且$n$足够大,我们只需要尝试几个较小的奇数就可以找到。实际上,因为$n-1$是偶数,而奇数$a$的范围可以从3到$n-4$,所以总存在一个$a$使得$\gcd(a, n-1-a)=1$?并且由于$n$足够大,我们可以很快找到。 但是,我们能不能不枚举?我们可以取$a$为小于$n-1$的一个质数$p$,那么只要$n-1-p$不是$p$的倍数,那么$\gcd(p, n-1-p)=1$。因为$n-1-p$如果是$p$的倍数,则$n-1-p \equiv 0 \pmod p$,即$n-1 \equiv 0 \pmod p$,所以$p$是$n-1$的因子。那么,我们取一个不是$n-1$的因子的质数$p$,且$p<n-1$,那么一定满足$\gcd(p, n-1-p)=1$。由于$n-1$的因子个数有限,而小于$n-1$的质数很多,所以一定存在。 在竞赛中,我们可以这样构造: - 当$n$是偶数时,取$a=2, b=n-3, c=1$。 - 当$n$是奇数时,取$a$为一个很小的奇质数(比如3),然后检查$b=n-1-a$是否与$a$互质(即检查$\gcd(a, b)=1$),如果成立,则输出$a, b, c=1$;否则,尝试下一个质数(比如5)。由于$n$比较大,很快就能找到。 实际上,我们可以取$a$为3,5,7,...,不一定非要是质数,只要$a$和$b$互质即可。但是,使用质数可以更快地排除倍数关系。我们可以从3开始,每次加2(保证是奇数),然后检查$\gcd(a, n-1-a)=1$,直到找到为止。由于$n$很大,而$n-1$的因子个数很少,所以很快就能找到一个与$n-1$互质的$a$(注意,这里不是要求$a$与$n-1$互质,而是要求$a$与$b=n-1-a$互质,而$\gcd(a, b)=\gcd(a, n-1)$,因为$b=n-1-a$,所以$\gcd(a, b)=\gcd(a, n-1-a)=\gcd(a, n-1)$。因此,我们需要$\gcd(a, n-1)=1$。那么,我们只需要选择一个与$n-1$互质的数$a$($2\leq a \leq n-3$)即可。由于$n-1$是偶数(当$n$为奇数时),所以$a$不能是偶数(否则$\gcd(a, n-1)\ge2$),所以$a$必须是奇数。而$n-1$的质因子是有限的,我们只需要选一个不包含$n-1$的质因子的数。我们可以选择$a$为大于1的最小奇数,使得$\gcd(a, n-1)=1$。例如,$n=15$(奇数),$n-1=14$,14的质因子为2和7。那么我们可以取$a=3$(3和14互质),则$b=14-3=11$,$\gcd(3,11)=1$,所以$a=3, b=11, c=1$。 所以构造方法: 1. 令$c=1$。 2. 若$n$为偶数,则取$a=2$,$b=n-3$(因为$n$为偶数,$n-3$为奇数,$\gcd(2, n-3)=1$)。 3. 若$n$为奇数,则取一个最小的奇数$a$($a\ge3$),使得$\gcd(a, n-1)=1$。由于$n-1$是偶数,且$a$是奇数,所以$\gcd(a, n-1)$只与$n-1$的奇质因子有关。我们可以从3开始,5,7,...递增,直到找到一个与$n-1$互质的$a$,然后令$b=n-1-a$。 注意:$a$必须小于$n-1$,且大于1,并且与$b$不同(因为$b=n-1-a$,而$a$至少为3,$b$至少为$n-1-3$,而$n>=10$,所以$b$至少为6,所以不会相等。同时,$c=1$,与$a,b$不同。 因此,算法步骤: - 读入$n$ - $c=1$ - 如果$n$是偶数: - $a=2$ - $b=n-3$ - 否则($n$是奇数): - $m = n-1$ - $a=3$ - 循环,直到$\gcd(a, m)==1$: $a = a+2$ # 注意,这里每次加2,保持为奇数 - $b = m - a$ - 输出$a, b, c$ 但是,这里有一个问题:当$n$是奇数时,$a$从3开始,然后5,7,...,直到找到与$m$互质的数。由于$m$是偶数,所以$a$只需要是奇数,且与$m$没有共同的奇质因子。而$m$的奇质因子个数有限,所以很快。但是,要确保$a$和$b$都是正整数,且$a,b\ge2$。由于我们取$a$至少为3,那么$b=m-a$,而$m=n-1$,$n\ge10$,$m\ge9$,$a$最大不会超过$m-2$(因为至少留2给$b$),所以$b\ge2$。 但是,在循环中,$a$会一直增加,直到找到满足条件的$a$。由于$m$是偶数,所以一定存在奇数$a$使得$\gcd(a, m)=1$(例如,取$a$为大于$m$的最大质数?不对,我们是从小到大取)。实际上,由于$m$的互质数一定存在,且小于$m$的互质数有很多,所以很快。 但是,我们可以优化:因为$m$的质因子是固定的,我们可以预先知道$m$的质因子,然后跳过这些质因子的倍数。但在竞赛中,直接枚举奇数并检查gcd即可,因为$m$的质因子个数很少,枚举次数不会很多。 另外,注意特殊情况:当$n$为奇数时,$a$不能取$m$的质因子的倍数。例如,$m$有质因子3,5,7等,那么$a$就不能是3,5,7的倍数。但是,我们从小到大取奇数,第一个不被$m$的质因子整除的奇数就是我们要的。由于$m$的质因子集合为$S$,那么最小的不包含$S$中因子的奇数可能很小。 例如,$m=14$(当$n=15$),质因子为2和7(但2不考虑,因为$a$是奇数),那么$a$不能是7的倍数。最小的奇数3,3不是7的倍数,所以取3。 再如,$m=30$($n=31$),质因子有2,3,5(奇数因子为3,5),那么最小的奇数3是3的倍数,跳过;5是5的倍数,跳过;7不是3或5的倍数,所以取7,$b=30-7=23$,$\gcd(7,23)=1$,成立。 因此,我们可以这样实现。 但是,题目要求$c$是正整数,且$a,b,c$互不相同。在我们的构造中,$c=1$,$a$和$b$都大于1,且$a$和$b$不相等(因为$n-1$是偶数,而$a$和$b$都是奇数,且$a \neq b$,因为如果$a=b$,则$a+a=n-1$,即$2a=n-1$,但$n-1$是偶数,所以$a$为整数,但此时$a=(n-1)/2$,那么$b=(n-1)/2$,与$a$相等,但题目要求互不相同。因此,我们取$a$和$b$不相等,而我们的构造中,$a$从3开始,$b=n-1-a$,而$n-1\ge9$,$a$最小为3,$b$最小为$n-1-3\ge6$,所以$a$和$b$不相等。同时,$c=1$,与$a,b$也不相等(因为$a,b\ge3$和$6$,都大于1)。 但是,当$n$为偶数时,$a=2$,$b=n-3$,$c=1$,那么$2$和$1$不相等,$n-3$和$1$也不相等,$2$和$n-3$:当$n=10$时,$b=7$,所以2和7不相等;当$n=12$时,$b=9$,2和9也不相等。所以满足。 因此,我们总结: - 对于任意$n \ge 10$,令$c=1$。 - 如果$n$是偶数,则令$a=2, b=n-3$。 - 如果$n$是奇数,则从$a=3$开始,每次$a$增加2(保持为奇数),直到找到一个$a$使得$\gcd(a, n-1)=1$,然后令$b=n-1-a$。 注意:在$n$为奇数时,$a$的取值范围是$3\le a \le n-4$(确保$b=n-1-a\ge2$,即$a\le n-3$)。由于$n$是奇数且$n\ge10$,$n-1\ge9$,所以$a$从3到$n-4$(奇数)是可行的。 代码实现(C++): ```cpp #include <iostream> #include <cmath> using namespace std; int gcd(int a, int b) { if (b == 0) return a; return gcd(b, a % b); } int main() { int t; cin >> t; while (t--) { int n; cin >> n; int a, b, c = 1; if (n % 2 == 0) { a = 2; b = n - 3; } else { int m = n - 1; // m is even a = 3; // 循环直到找到一个a使得gcd(a, m)==1 while (gcd(a, m) != 1) { a += 2; } b = m - a; } cout << a << " " << b << " " << c << endl; } return 0; } ``` 注意:在$n$为奇数时,$a$从3开始,每次加2,直到找到满足条件的$a$。由于$m$是偶数,而$a$是奇数,所以$\gcd(a, m)$可能大于1,但总存在一个奇数$a$(比如大于$m$的最大质因子)与$m$互质,所以循环会终止。 这个算法的时间复杂度:最坏情况下,$m$的奇质因子很多,但$m$不超过$2\cdot10^5$(题目中$n$的范围?题目没有给出具体范围,但$n\ge10$,且$t$组测试数据,$t$最多多少?题目没给,但一般$t$不超过$10^4$。而内层循环次数:最坏情况下,$m$的互质奇数最小是多少?根据数论,不超过$m$的互质数存在,且最小的大概在$O(\log m)$级别?实际上,最坏情况下,我们枚举的次数最多为$m$的奇质因子个数乘以某个常数,而$m$的质因子个数为$O(\log m)$,所以枚举次数最多几十次。所以总复杂度为$O(t \cdot \log n)$,可以接受。 因此,按照这个方案即可。 输出格式:对于每个测试用例,输出三个整数$a, b, c$,满足条件。 现在,按照用户要求,生成相关问题。 相关问题: 1. 为什么在$n$为奇数时,需要寻找一个与$n-1$互质的奇数$a$? 2. 如何证明在$n$为奇数时,一定存在一个奇数$a$($3\le a\le n-4$)满足$\gcd(a, n-1)=1$? 3. 除了$c=1$的构造,还有没有其他构造方法? 4. 如果$n$小于10,题目是否有解? </think>### Codeforces 1617B "GCD Problem" 解题方案 #### 题目描述 给定一个整数 $n$($n \geq 10$),要求找到三个**互不相同**的正整数 $a, b, c$,满足以下条件: 1. $a + b + c = n$ 2. $\gcd(a, b) = c$ #### 解题思路 1. **核心观察**: 由于 $\gcd(a, b) = c$,可设 $a = c \cdot d$,$b = c \cdot e$,其中 $d$ 和 $e$ 互质($\gcd(d, e) = 1$)。 则原条件转化为: $$ c \cdot d + c \cdot e + c = n \implies c \cdot (d + e + 1) = n $$ 因此,$c$ 必须是 $n$ 的因子。但直接枚举因子较复杂,可通过构造简化。 2. **关键构造**: 固定 $c = 1$,则问题简化为: - $d + e = n - 1$ - $\gcd(d, e) = 1$ - $d, e \geq 2$(确保 $a, b, c$ 互不相同) 3. **分类讨论**: - **当 $n$ 为偶数时**: $n - 1$ 是奇数,取 $d = 2$,$e = n - 3$。 此时 $\gcd(2, n - 3) = 1$(因为 $n - 3$ 是奇数),且 $a = 2, b = n - 3, c = 1$ 互不相同。 - **当 $n$ 为奇数时**: $n - 1$ 是偶数,需寻找奇数 $d \geq 3$ 使得 $\gcd(d, n - 1) = 1$(因为 $\gcd(d, e) = \gcd(d, n - 1)$)。 从 $d = 3$ 开始,每次增加 2(保持奇数),直到找到满足条件的 $d$,则 $e = n - 1 - d$。 #### 代码实现(C++) ```cpp #include <iostream> using namespace std; int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } int main() { int t; cin >> t; while (t--) { int n; cin >> n; int a, b, c = 1; if (n % 2 == 0) { a = 2; b = n - 3; } else { int m = n - 1; a = 3; while (gcd(a, m) != 1) { a += 2; } b = m - a; } cout << a << " " << b << " " << c << endl; } return 0; } ``` #### 算法分析 - **正确性**: - $n$ 为偶数时,$a=2, b=n-3, c=1$ 满足 $\gcd(2, n-3)=1$ 且互不相同。 - $n$ 为奇数时,由于 $n-1$ 的互质数一定存在,且奇数 $d$ 的枚举范围 $[3, n-4]$ 足够大,必能找到解。 - **时间复杂度**: - 外层循环 $t$ 次(测试用例数),内层循环最多 $O(\log n)$ 次(与 $n-1$ 的质因子个数相关)。 - 整体复杂度 $O(t \log n)$,满足竞赛要求。 #### 示例 - **输入**:$n = 10$(偶数) **输出**:$a=2, b=7, c=1$($2+7+1=10$,$\gcd(2,7)=1$) - **输入**:$n = 15$(奇数) **输出**:$a=3, b=11, c=1$($3+11+1=15$,$\gcd(3,11)=1$) [^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值