开始补AtCoder的数学题了,练下思维

AB两道都很简单,看懂题就OK。

C,D稍微麻烦一些

Problem C: GCD On Blackboard

为了解决此问题,我们需要了解最大公约数(GCD)的某些属性。

第一点是,GCD是可交换的(GCD(a,b)= GCD(b,a))。

第二个是3个数字的GCD是关联的(GCD(a,GCD(b,c))= GCD(GCD(a,b),c))。

最后,在不失一般性的前提下,如果a和b是2个正数且a <= b,则GCD(a,b)<= a。 换句话说,2个数字的GCD最多等于较小的数字。

回到问题陈述,我们有一个数字列表,可以修改列表中的一个数字,然后用另一个数字替换它,以使列表的GCD最大化。 让我们将关于GCD的已知知识应用于此问题:

假设我们的列表 \(A = A_1,A_2,A_3,...,A_n\),我们希望修改索引 \(A_i\)。 根据关联规则,我们知道:GCD(A1,A2,A3,...,Ai,...,An)可以重新排序为:GCD(A1,A2,A3,...,An,Ai)。 换句话说,我们可以计算除 \(A_i\)以外的所有数字的GCD,然后使用\(A_i\)计算结果的GCD的结果。 令g为除\(A_i\)以外的所有数字的GCD。 现在我们希望最大化GCD(g,Ai)。 由于对\(A_i\)进行简化后我们可以获得的最大GCD为g,因此答案为g。

因此,我们知道在位置i处可获得的最大gcd是除\(A_i\)以外的所有数字的gcd。 如果我们在每个 \(i\) 处计算这些gcd值,则所有结果的最大值是修改列表中的数字后可能的最大GCD。

那么我们将如何实现该算法? 为方便起见,让我们定义\(R_i\)和\(L_i\)的两个功能,如下所示:

\[R_{n + 1} = 0\\R_i = GCD(R_{i + 1},A_i)\\L_0= 0\\L_i = GCD(L_{i - 1},A_i)
\]

\(L_i\)代表A1…Ai的gcd,\(R_i\)代表Ai…An的GCD。 如果我们希望找到除Ai以外的所有元素的GCD,则可以找到Mi = GCD(Li-1,Ri + 1)。 这表示除Ai以外的所有数字的GCD。

我们可以预先计算R和L。最后,我们可以找到Mi的每个值,然后计算出最大值,这就是我们的答案。 示例代码如下(复杂度为\(O(n)\)):

const int N = 100000 + 5;
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
// L_i = gcd(A_1, A_2, A_3, ... A_i)
// R_i = gcd(A_i, A_{i+1}, A_{i+1}, ..., A_n)
int n;
ll a[N], L[N], R[N];
cin >> n; for (int i = 1; i <= n; ++i) {
cin >> a[i];
L[i] = R[i] = a[i];
} // precomputing L[i]
for (int i = 1; i <= n; i++) {
L[i] = __gcd(L[i], L[i - 1]);
}
// precomputing R[i]
for (int i = n; i > 0; i--) {
R[i] = __gcd(R[i], R[i + 1]);
} // computing each m_i and the max value
int res = 0;
for (int i = 1; i <= n; i++) {
int m = __gcd(L[i - 1], R[i + 1]);
res = max(m, res);
} cout << res;
return 0;
}

Problem D: Flipping Signs

让我们考虑元素A1,A2,A3,…,An的列表。 我们被允许翻转任意两个连续元素Ai和Ai + 1的符号。 需要注意的一个有用观察结果是(除了最后一个元素),我们可以翻转任何Ai的符号而不会影响Ai-1。

但是我们如何利用这个事实呢? 好吧,我们知道我们可以使从i = 1到i = n-1的每个元素对于任何列表都是正的。 由于我们不在乎操作数量,因此这种贪婪的方法效果很好。

给定任何数字A列表,我们将能够使用此方法使除最后一个元素之外的所有Ai均为正。 最后一个元素将为负或正。 让我们分别处理这种情况。

所以现在我们可以将最后一个元素设为正数或负数。 如果为正,则所有元素均为正,列表的总和就是我们的答案。 如果它是负数,那么我们需要检查一些变化以获得最大的总和结果。 首先,我们需要检查最后两个元素中哪个更大。 由于我们可以使最后一个元素为正,而使An-1为负。 实际上,我们可以使任何一个Aj为负(j <n),以使最后一个元素为正。 考虑三个连续的正a,b,c元素。 我们首先可以翻转a和b的符号,这将使它们变为负数。 在下一步中,我们可以翻转b的符号,这将使b变为正,而c变为负。 这将使a变为负数,我们可以再次翻转c的符号使其变为正数,依此类推。 我们可以链接此操作,该操作将只留下a为负数,其余元素保持正值(最后一个元素除外,该元素将从负数变为正数)。

因此,我们有了算法最后一步的配方:我们检查范围A1…An-1中的最小元素。 将此最小元素称为m。 如果m <An,则将m的符号翻转为负,然后使An为正。 否则,我们将m保持为正。 这个清单的总和就是我们的答案。

Bellow是此解决方案的C ++实现。 注意,该解决方案与列表的其余部分分开处理An-1,An的情况,但是它与上述算法相同。

using ll = long long;
const int N = 1e5 + 10;
int main() {
ios_base::sync_with_stdio(false), cin.tie(0);
int n, A[N];
// store the sum of the result in a long long pair
ll s = 0;
cin >> n;
for (int i = 1; i <= n; ++i) cin >> A[i]; for (int i = 1; i <= n - 2; ++i) {
if (A[i] < 0) A[i] *= -1, A[i + 1] *= -1;
s += A[i];
} // if n is 2, we only need to consider those
// Also , if the last 2 elements are either both positive
// or both negative then we simply flip their signs too
if ((n == 2) or (A[n] > 0 and A[n - 1] > 0) or (A[n] < 0 and A[n - 1] < 0))
s += max(A[n - 1] + A[n], -A[n - 1] - A[n]);
else {
// find the min element in the list (excluding last 2 elements)
int* mni = min_element(A + 1, A + n - 2);
int mnv = *mni; // if the minimum value in the remaining list is larger than
// the smaller value of the last 2 elements, then we should
// just keep it positive
if (mnv > min(abs(A[n - 1]), abs(A[n]))) {
s += max(A[n - 1] + A[n], -A[n - 1] - A[n]);
}
// otherwise, we can make that value negative, and include the
// last 2 elements as positive elements
else {
s -= mnv * 2;
s += abs(A[n - 1]);
s += abs(A[n]);
}
}
cout << s << "\n"; return 0;
}

AtCoder | ABC 125 Person Editorial的更多相关文章

  1. ATCODER ABC 099

    ATCODER ABC 099 记录一下自己第一场AK的比赛吧...虽然还是被各种踩... 只能说ABC确实是比较容易. A 题目大意 给你一个数(1~1999),让你判断它是不是大于999. Sol ...

  2. Atcoder ABC 141

    Atcoder ABC 141 A - Weather Prediction SB题啊,不讲. #include<iostream> #include<cstdio> #inc ...

  3. Atcoder ABC 139E

    Atcoder ABC 139E 题意: n支球队大循环赛,每支队伍一天只能打一场,求最少几天能打完. 解法: 考虑抽象图论模型,既然一天只能打一场,那么就把每一支球队和它需要交手的球队连边. 求出拓 ...

  4. Atcoder ABC 139D

    Atcoder ABC 139D 解法: 等差数列求和公式,记得开 $ long long $ CODE: #include<iostream> #include<cstdio> ...

  5. Atcoder ABC 139C

    Atcoder ABC 139C 题意: 有 $ n $ 个正方形,选择一个起始位置,使得从这个位置向右的小于等于这个正方形的高度的数量最多. 解法: 简单递推. CODE: #include< ...

  6. Atcoder ABC 139B

    Atcoder ABC 139B 题意: 一开始有1个插口,你的插排有 $ a $ 个插口,你需要 $ b $ 个插口,问你最少需要多少个插排. 解法: 暴力模拟. CODE: #include< ...

  7. Atcoder ABC 139A

    Atcoder ABC 139A 题意: 给你两个字符串,记录对应位置字符相同的个数 $ (n=3) $ 解法: 暴力枚举. CODE: #include<iostream> #inclu ...

  8. atcoder abc 244

    atcoder abc 244 D - swap hats 给定两个 R,G,B 的排列 进行刚好 \(10^{18}\) 次操作,每一次选择两个交换 问最后能否相同 刚好 \(10^{18}\) 次 ...

  9. AtCoder ABC 250 总结

    AtCoder ABC 250 总结 总体 连续若干次一样的结果:30min 切前 4 题,剩下卡在 T5 这几次卡在 T5 都是一次比一次接近, 什么 dp 前缀和打挂,精度被卡,能水过的题连水法都 ...

  10. AtCoder ABC 242 题解

    AtCoder ABC 242 题解 A T-shirt 排名前 \(A\) 可得 T-shirt 排名 \([A+1,B]\) 中随机选 \(C\) 个得 T-shirt 给出排名 \(X\) ,求 ...

随机推荐

  1. 本地训练,立等可取,30秒音频素材复刻霉霉讲中文音色基于Bert-VITS2V2.0.2

    之前我们使用Bert-VITS2V2.0.2版本对现有的原神数据集进行了本地训练,但如果克隆对象脱离了原神角色,我们就需要自己构建数据集了,事实上,深度学习模型的性能和泛化能力都依托于所使用的数据集的 ...

  2. .NET生成微信小程序推广二维码

    前言 对于小程序大家可能都非常熟悉了,随着小程序的不断普及越来越多的公司都开始推广使用起来了.今天接到一个需求就是生成小程序码,并且与运营给的推广图片合并在一起做成一张漂亮美观的推广二维码,扫码这种二 ...

  3. ERP到底是什么?

    ERP,全称企业资源计划,ERP系统主要是优化企业内部的业务流程,用信息化管控的方式进行一系列板块的管理,它可以看作是进销存系统的进阶版,主要针对供应链中下游. ERP的业务覆盖范围广,实际上它更加侧 ...

  4. Opencv学习笔记(2)

    图像处理是图像识别过程中重要一环,一张图像可能包括海量的不明确的信息,图像处理的目的是消除图像中无关的信息,恢复有用的真实信息,增强有效信息的可检测性,最大限度地简化数据. 参考知乎文章链接:http ...

  5. 2分钟,快速认识什么是SQL

    结构化查询语言,简称SQL,它是与关系数据库管理系统通信的黄金标准语言.今天就来一起快速认识一下什么是SQL,您可以通过以下的文字内容学习,也可以通过文末的视频学习,希望本文对您有所帮助. 您可能听说 ...

  6. HTML中的三个列表,具体的使用及列表样式

    HTML有三种列表:## 一.有序列表 有序列表(Ordered lists):用数字或字母来标记列表项,每个列表项前会有一个数字或字母. ```html<ol> <li>列表 ...

  7. 前端 JS 安全对抗原理与实践

    作者:vivo 互联网安全团队- Luo Bingsong 前端代码都是公开的,为了提高代码的破解成本.保证JS代码里的一些重要逻辑不被居心叵测的人利用,需要使用一些加密和混淆的防护手段. 一.概念解 ...

  8. CVE-2023-36025 Windows SmartScreen 安全功能绕过漏洞

    CVE-2023-36025是微软于11月补丁日发布的安全更新中修复Windows SmartScreen安全功能绕过漏洞.攻击者可以通过诱导用户单击特制的URL来利用该漏洞,对目标系统进行攻击.成功 ...

  9. windows 和 Linux 下 git status 结果不一致

    解决该问题 运行一下命令即可 git config core.autocrlf true 解释 git config core.autocrlf true 这个命令是在任何支持的操作系统上都可以运行的 ...

  10. 未经授权访问 .js

    流程顺序:后台管理登陆地址 → 后台主页地址 → fuzz测试出用户管理列表接口 → 直接调接口..全程黑盒. 那么接下来我逆着来推理下逻辑: 首先是拿到某后台管理登录的网址 接着查看html源码,发 ...