【枚举】P6786「SWTR-6」GCDs & LCMs|普及+

本文涉及知识点

枚举

「SWTR-6」GCDs & LCMs

题目描述

小 A 有一个长度为 n n n 的序列 a 1 , a 2 , ⋯   , a n a_1,a_2,\cdots,a_n a1,a2,⋯,an。

他想从这些数中选出一些数 b 1 , b 2 , ⋯   , b k b_1,b_2,\cdots,b_k b1,b2,⋯,bk 满足:对于所有 i ( 1 ≤ i ≤ k ) i\ (1\leq i\leq k) i (1≤i≤k), b i b_i bi 要么是序列 b b b 中的最大值,要么存在一个位置 j j j 使得 b j > b i b_j>b_i bj>bi 且 b i + b j + gcd ⁡ ( b i , b j ) = l c m ( b i , b j ) b_i+b_j+\gcd(b_i,b_j)=\mathrm{lcm}(b_i,b_j) bi+bj+gcd(bi,bj)=lcm(bi,bj)。

  • 如果你不知道 gcd ⁡ \gcd gcd 和 l c m \mathrm{lcm} lcm 是什么,可以点击最底部的「帮助/提示」部分的链接。

小 A 想让选出的数之和尽量大。请求出这个最大值。

输入格式

第一行一个整数 n n n,表示序列的长度。

第二行 n n n 个整数 a 1 , a 2 , ⋯   , a n a_1,a_2,\cdots,a_n a1,a2,⋯,an。

输出格式

输出一行一个整数表示答案。

样例 #1

样例输入 #1

复制代码
4
4 3 2 1

样例输出 #1

复制代码
5

样例 #2

样例输入 #2

复制代码
10
6 7 18 4 17 10 9 1 3 8

样例输出 #2

复制代码
19

样例 #3

样例输入 #3

复制代码
3
123456789 234567890 123456789

样例输出 #3

复制代码
246913578

提示

「样例 1 说明」

可以选择 b = { 2 , 3 } b=\{2,3\} b={2,3},因为 2 + 3 + gcd ⁡ ( 2 , 3 ) = l c m ( 2 , 3 ) 2+3+\gcd(2,3)=\mathrm{lcm}(2,3) 2+3+gcd(2,3)=lcm(2,3)。

「数据范围与约定」

本题采用捆绑测试。

  • Subtask 1(5 points): n ≤ 2 n\leq2 n≤2;
  • Subtask 2(20 points): n ≤ 17 n\leq 17 n≤17;
  • Subtask 3(15 points): a i ≤ 2 × 10 3 a_i\leq 2\times 10^3 ai≤2×103;
  • Subtask 4(15 points): n ≤ 2 × 10 3 n\leq 2\times 10^3 n≤2×103;
  • Subtask 5(10 points): n ≤ 5 × 10 4 n\leq 5\times 10^4 n≤5×104;
  • Subtask 6(10 points): a i ≤ 10 7 a_i\leq 10^7 ai≤107;
  • Subtask 7(25 points):无特殊限制。

对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 3 × 10 5 1\leq n\leq 3\times 10^5 1≤n≤3×105, 1 ≤ a i ≤ 10 9 1\leq a_i\leq 10^9 1≤ai≤109。

「帮助/提示」

gcd ⁡ \gcd gcd 表示最大公约数, l c m \mathrm{lcm} lcm 表示最小公倍数

「来源」

【LGR-075】洛谷 8 月月赛 II Div.2 & SWTR-06 & EZEC Round 3

idea & solution & data by Alex_Wei

枚举

令bj,bj的最大公约数是x,令cx=bi,dx=bj,则c<d,c和d互质,x>0。上式    ⟺    \iff ⟺ cx+dx+x = cdx    ⟺    \iff ⟺ c+d+1 = cd

即:(c-1)(d-1)=2
由于0 <= c <=d,且是整数。故:c等于2,d等于3。
即序列b是一个比为3/2的等比序列。
有序集合s记录a。哈希映射e[i]记录以i结尾的最长序列和。
通过i枚举s,如果i是3的倍数,e[i] = i +e[i/3
2],否则e[i] = i。

max(e)就是最大值。
注意:如果一个数出现多次,可以被选择多次。

代码

核心代码

cpp 复制代码
#include <iostream>
#include <sstream>
#include <vector>
#include<map>
#include<unordered_map>
#include<set>
#include<unordered_set>
#include<string>
#include<algorithm>
#include<functional>
#include<queue>
#include <stack>
#include<iomanip>
#include<numeric>
#include <math.h>
#include <climits>
#include<assert.h>
#include<cstring>

#include <bitset>
using namespace std;

template<class T1, class T2>
std::istream& operator >> (std::istream& in, pair<T1, T2>& pr) {
	in >> pr.first >> pr.second;
	return in;
}

template<class T1, class T2, class T3 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3>& t) {
	in >> get<0>(t) >> get<1>(t) >> get<2>(t) ;
	return in;
}

template<class T1, class T2, class T3, class T4 >
std::istream& operator >> (std::istream& in, tuple<T1, T2, T3, T4>& t) {
	in >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t);
	return in;
}

template<class T = int>
vector<T> Read() {
	int n;
	scanf("%d", &n);
	vector<T> ret(n);
	for(int i=0;i < n ;i++) {
		cin >> ret[i];
	}
	return ret;
}

template<class T = int>
vector<T> Read(int n) {
	vector<T> ret(n);
	for (int i = 0; i < n; i++) {
		cin >> ret[i];
	}
	return ret;
}

class Solution {
		public:	
			long long Ans(vector<int>& a) {
				map<int, int> mCnt;
				for (const auto& i : a) {
					mCnt[i]++;
				}
				unordered_map<int, long long> mSum;
				long long llMax = 0;
				for (const auto& [i,cnt] : mCnt) {
					if (0 == i % 3) {
						mSum[i] = i*(long long)cnt + mSum[i / 3 * 2];
					}
					else {
						mSum[i] = i * (long long)cnt;
					}
					llMax = max(llMax, mSum[i]);
				}
				return llMax;
			}
		};

int main() {
#ifdef _DEBUG
	freopen("a.in", "r", stdin);
#endif // DEBUG		
	auto a = Read<int>();	
#ifdef _DEBUG		
	//printf("K=%d", K);
	//Out(a, "a=");
#endif // DEBUG	
	auto res = Solution().Ans(a);
	cout << res << endl;
	return 0;
}

单元测试

cpp 复制代码
vector<int> a;
		int K;
		TEST_METHOD(TestMethod11)
		{
			a = { 4,3,2,1 }	;
			auto res = Solution().Ans(a);
			AssertEx(5LL, res);
		}
		TEST_METHOD(TestMethod12)
		{
			a = { 6,7,18,4,17,10,9,1,3,8 };
			auto res = Solution().Ans(a);
			AssertEx(19LL, res);
		}
		TEST_METHOD(TestMethod13)
		{
			a = { 123456789,234567890,123456789 };
			auto res = Solution().Ans(a);
			AssertEx(246913578LL, res);
		}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法用**C++**实现。

相关推荐
BB学长1 小时前
LBM vs FVM:谁才是 CFD 的未来?
人工智能·算法·机器学习
m0_716667072 小时前
实时数据压缩库
开发语言·c++·算法
dapeng28702 小时前
多协议网络库设计
开发语言·c++·算法
星空露珠2 小时前
又双叒叕统计被炸死的lua脚本
开发语言·数据结构·算法·游戏·lua
阿Y加油吧2 小时前
力扣打卡——day01
java·算法·leetcode
阿猿收手吧!2 小时前
【C++】建造者与代理模式实战解析
开发语言·c++·代理模式
Suifqwu2 小时前
stm32之移植MbedTLS以及算法实现
stm32·嵌入式硬件·算法
墨染天姬2 小时前
【AI】AutoResearch将一定程度上替代算法工程师
人工智能·算法
2501_945424803 小时前
C++跨平台开发实战
开发语言·c++·算法