首页 > 其他分享 >洛谷P6786

洛谷P6786

时间:2024-08-03 13:27:40浏览次数:11  
标签:... 洛谷 gcd int ll 2y P6786 lcm

题目

原题链接

https://www.luogu.com.cn/problem/P6786

题目描述

小 A 有一个长度为 n 的序列 a_1, a_2, ..., a_n
他想从这些数中选出一些数 b_1, b_2, ..., b_k 满足:对于所有 i (1 <= i <= k),b_i 要么是序列 b 中的最大值,要么存在一个位置 j 使得 b_j > b_i

b_i + b_j + gcd(b_i, b_j) = lcm(b_i, b_j)

如果你不知道 gcdlcm 是什么,可以点击最底部的「帮助/提示」部分的链接。
小 A 想让选出的数之和尽量大。请求出这个最大值。

输入格式

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

第二行 n 个整数 a_1, a_2, ..., a_n

输出格式

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

结论 1

对于任意 xy 满足

x + y + gcd(x, y) = lcm(x, y)

总有 x = (3/2) * yy = (3/2) * x

证明 1

不妨设 x <= y。当 x = y 时,原式不成立,因此 x < y

因为 x < y,所以 gcd(x, y) < y。从而:

x + y + gcd(x, y) < 3y

又因为:

x + y + gcd(x, y) > y

lcm(x, y)y 的整数倍。因此:

x + y + gcd(x, y) = 2y

所以:

lcm(x, y) = 2y

lcm(x, y) * gcd(x, y) = x * y 可得:

x * y = 2y * gcd(x, y)

从中得到:

gcd(x, y) = x / 2

代入原式:

x + y + (x / 2) = 2y

解得:

x = (3/2) * y

y = (3/2) * x

推论 1.1

根据结论 1,对于每个偶数 x,满足 x + y + gcd(x, y) = lcm(x, y) 且大于 xy 有且只有一个,即 y = (3/2) * x。对于奇数,则不存在这样的 y

根据上面的结论,我们很容易得出,如果将选出来的数从小到大排序,去重,满足:

b_i = (3/2) * b_{i+1} (1 <= i < k)

代码

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
    int n;
    cin >> n;
    vector<ll> k(n);
    for (int i = 0; i < n; ++i) cin >> k[i];
    
    sort(k.begin(), k.end(), greater<ll>());
    map<ll, ll> M;
    
    // 初始化只有一个数字的情况
    for (int i = 0; i < n; ++i) M[k[i]] += k[i];
    
    for (int i = n - 1; i >= 0; --i) {
        // 相同数字重复计算跳过
        if (i < n - 1 && k[i] == k[i + 1]) continue;
        
        // 奇数明显不行
        if (k[i] % 2 != 0) continue;
        
        ll t = k[i] / 2 * 3;
        
        // 可以状态连接到前面
        if (M.find(t) != M.end()) {
            M[t] += M[k[i]];
        }
    }
    
    // 输出最大值
    ll res = 0;
    for (const auto& entry : M) {
        res = max(res, entry.second);
    }
    cout << res << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
    return 0;
}

标签:...,洛谷,gcd,int,ll,2y,P6786,lcm
From: https://www.cnblogs.com/yuzhongrun/p/18340358

相关文章

  • 洛谷P4554 小明的游戏
    小明的游戏题目描述小明最近喜欢玩一个游戏。给定一个n×m的棋盘,上面有两种格子#和@。游戏的规则很简单:给定一个起始位置和一个目标位置,小明每一步能向上,下,左,右四个方向移动一格。如果移动到同一类型的格子,则费用是0,否则费用是1。请编程计算从起始位置移动到目标位置的最小......
  • 洛谷 P1080 [NOIP2012 提高组] 国王游戏
    一道非常有挑战性的题目(~太难了~)。这题我们可以用贪心来做。思路:首先我们定义一个结构体struct,里面放的是每个人左手和右手的数字。接着我们需要一种排列方式,使得获得奖赏最多的大臣,所获奖赏尽可能的少;这句话听起来是不是听绕口?意思就是说得到奖赏数量最多,但加起来的总奖赏......
  • 洛谷-P3869 [TJOI2009] 宝藏
    Abstract传送门本题是状态压缩+记忆化BFS的典型例子。Idea要求从出发点到终点的最短步数,BFS自然是首选的方法,那么,如何构造搜索的每一个节点呢?考虑到机关的数量比较小,最多10种,我们可以考虑用状态压缩去描述机关当前的状态,然后再记录当前的横纵坐标,以及行走的步数即可。值得......
  • 洛谷 P1052 [NOIP2005 提高组] 过河
    原题https://www.luogu.com.cn/problem/P1052题目描述在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:1,⋯,L......
  • 洛谷P3161 [CQOI2012] 模拟工厂 贪心策略的思考
    P3161[CQOI2012]模拟工厂传送门:模拟工厂问题描述:初始的生产力和商品分别为1和0。每一个时刻可以选择两个动作:生产力+1或者生产生产力数量的商品。现在有很多个订单,每个订单有三个部分:时间t,需要多少商品p,可以获得的价值v。现在需要决定各个时刻的动作选择,以及订单是否接取,以期......
  • 洛谷题单指南-前缀和差分与离散化-P3029 [USACO11NOV] Cow Lineup S
    原题链接:https://www.luogu.com.cn/problem/P3029题意解读:不同的坐标位置有不同种类的牛,要计算一个最小的区间,包括所有种类的牛。解题思路:由于坐标位置不连续,并且数值范围较大,因此需要离散化处理,将坐标处理成1~n连续分布由于种类编号数值范围也比较大,也需要离散化处理,去重后的......
  • 洛谷P2801 教主的魔法之分块板子
    洛谷P2801题解传送锚点摸鱼环节教主的魔法题目描述教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是\(N\)个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为\(1,2,\ldots,N\)。每个人的身高一开始都是不超过\(1000\)......
  • 洛谷 B3612 【深进1.例1】求区间和
    "这道题也太水了吧,模拟就行了!""数据范围...""好像不行呀""呜呜~~TLE!"献上暴力代码!#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+5;intn,a[N],m;signedmain(){ios::sync_with_stdio(0);cin.tie(0);......
  • 洛谷题单指南-前缀和差分与离散化-P4552 [Poetize6] IncDec Sequence
    原题链接:https://www.luogu.com.cn/problem/P4552题意解读:对一组数字序列,进行若干次区间+1或者-1操作,最终使得所有数字一样,计算最少的操作次数,以及能得到多少种不同序列。解题思路:要使得序列每一个数字都相同,则其差分除了第一项之外其余项都是0。因此,问题转化为:给定一个差分数......
  • 洛谷题单指南-前缀和差分与离散化-P2882 [USACO07MAR] Face The Right Way G
    原题链接:https://www.luogu.com.cn/problem/P2882题意解读:一个有F、B组成的序列,每次可以翻转k个连续子序列,翻转:F->B,B->F,计算最少翻转多少次可以将序列都变成F,并求相应的k。解题思路:为方便处理,设F为1,B为01、朴素做法枚举k:1~n  枚举序列,一旦遇到0,就将连续k个字符翻转,如果可......