题解 P6786 【「SWTR-6」GCDs & LCMs】
因为是简单题所以放一下官方题解吧。
题面传送门。
题意简述:从给定序列
a 中选出一个子序列满足:对于所有不为最大值的b_i ,总有b_j 使得b_i+b_j+\gcd(b_i,b_j)=\mathrm{lcm}(b_i,b_j) 。求子序列所有数之和的最大值。
Subtask 1:
傻子都会做的部分分。
Subtask 2:
枚举
Subtask 4:
枚举所有
Subtask 3:
类似 Subtask 4 枚举权值,时间复杂度
结论 1:
对于任意
证明 1:
不妨设
因为
又因为
因为
带回原式得到
推论 1.1
根据结论 1,对于每个偶数
根据上面的结论,我们很容易得出,如果将选出来的数从小到大排序,去重,一定满足
Subtask 7:无特殊限制。
因此,
每个数最多只会被计算一次,总时间复杂度:二分
值得注意的是,如果不判断一个数是否被计算过,那么时间复杂度可能会退化成
Subtask 6 是给不会二分或 map 的参赛者准备的部分分(不过可能没多大必要)。
代码如下。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=3e5+5;
map <int,int> mp;
int n,a[N]; ll ans;
int main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],mp[a[i]]++;
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
ll tmp=a[i],cnt=0;
while(mp[tmp]){
cnt+=tmp*mp[tmp],mp[tmp]=0;
if(tmp%2==0)tmp=tmp/2*3;
else break;
}
ans=max(ans,cnt);
} cout<<ans<<endl;
return 0;
}