欢迎光临
我们一直在努力

小红与gcd和sum【牛客tracker & 每日一题】

小红与gcd和sum

时间限制:1秒 空间限制:1024M

网页链接

牛客tracker

牛客tracker & 每日一题,完成每日打卡,即可获得牛币。获得相应数量的牛币,能在【牛币兑换中心】,换取相应奖品!助力每日有题做,丰盈牛币日益多! 在这里插入图片描述

题目描述

小红很喜欢

g

c

d

gcd

gcd

s

u

m

sum

sum 。 小红定义一个长度为

k

k

k 的数组

{

a

1

,

a

2

,

,

a

k

}

\\{a_1,a_2,…,a_k\\}

{a1,a2,,ak} 的权值为

g

c

d

(

a

1

,

a

2

,

,

a

k

)

×

(

a

1

+

a

2

+

+

a

k

)

gcd⁡(a_1,a_2,…,a_k) × (a_1+a_2+⋯+a_k)

gcd(a1,a2,,ak)×(a1+a2++ak) 。 现在小芳给了小红一个长度为

n

n

n 的数组

{

a

1

,

a

2

,

,

a

n

}

\\{a_1,a_2,…,a_n\\}

{a1,a2,,an} ,小红可以从中挑选一个子序列带走。请你帮小红求出她能带走的权值最大的非空子序列。

【名词解释】

g

c

d

(

a

1

,

a

2

,

,

a

k

)

gcd⁡(a_1,a_2,…,a_k)

gcd(a1,a2,,ak) :即求解

a

1

,

a

2

,

,

a

k

a_1,a_2,…,a_k

a1,a2,,ak 的最大公约数,指所有整数共有约数中最大的一个。例如,

12

12

12

18

18

18

30

30

30 的公约数有

1

,

2

,

3

,

6

1,2,3,6

1,2,3,6 ,其中最大的约数是

6

6

6 ,因此

g

c

d

(

12

,

18

,

30

)

=

6

gcd⁡(12,18,30)=6

gcd(12,18,30)=6 。 非空子序列:从原序列中删除任意个(可以为零,但必须保留至少一个)元素后,保持剩余元素相对顺序不变得到的新序列。

输入描述:

第一行输入一个整数

n

(

1

n

10

5

)

n(1≦n≦10^5)

n(1n105) ,代表数组的长度。 第二行输入

n

n

n 个整数

a

1

,

a

2

,

,

a

n

(

1

a

i

10

6

)

a_1,a_2,…,a_n(1≦a_i≦10^6)

a1,a2,,an(1ai106) ,表示数组中的元素。

输出描述:

输出一个整数,代表权值最大子序列的权值。

示例1

输入:

3
2 6 4

输出:

36

说明:

在这个样例中,一共有

7

7

7 种不同的子序列选择方案:

  • {

    2

    }

    \\{2\\}

    {2} ,权值为

    2

    ×

    2

    =

    4

    2×2=4

    2×2=4

  • {

    6

    }

    \\{6\\}

    {6} ,权值为

    6

    ×

    6

    =

    36

    6×6=36

    6×6=36

  • {

    4

    }

    \\{4\\}

    {4} ,权值为

    4

    ×

    4

    =

    16

    4×4=16

    4×4=16

  • {

    2

    ,

    6

    }

    \\{2,6\\}

    {2,6} ,权值为

    g

    c

    d

    (

    2

    ,

    6

    )

    ×

    (

    2

    +

    6

    )

    =

    2

    ×

    8

    =

    16

    gcd⁡(2,6)×(2+6)=2×8=16

    gcd(2,6)×(2+6)=2×8=16

  • {

    2

    ,

    4

    }

    \\{2,4\\}

    {2,4} ,权值为

    g

    c

    d

    (

    2

    ,

    4

    )

    ×

    (

    2

    +

    4

    )

    =

    2

    ×

    6

    =

    12

    gcd⁡(2,4)×(2+4)=2×6=12

    gcd(2,4)×(2+4)=2×6=12

  • {

    6

    ,

    4

    }

    \\{6,4\\}

    {6,4} ,权值为

    g

    c

    d

    (

    6

    ,

    4

    )

    ×

    (

    6

    +

    4

    )

    =

    2

    ×

    10

    =

    20

    gcd⁡(6,4)×(6+4)=2×10=20

    gcd(6,4)×(6+4)=2×10=20

  • {

    2

    ,

    6

    ,

    4

    }

    \\{2,6,4\\}

    {2,6,4} ,权值为

    g

    c

    d

    (

    2

    ,

    6

    ,

    4

    )

    ×

    (

    2

    +

    6

    +

    4

    )

    =

    2

    ×

    12

    =

    24

    gcd⁡(2,6,4)×(2+6+4)=2×12=24

    gcd(2,6,4)×(2+6+4)=2×12=24 。 综上,权值最大的子序列是

    {

    6

    }

    \\{6\\}

    {6} ,权值为

    36

    36

    36

示例2

输入:

6
1 1 4 5 1 4

输出:

32

说明:

在这个样例中,选择

{

4

,

4

}

\\{4,4\\}

{4,4} 是最优的。

解题思路

本题核心是枚举公约数 + 贡献求和的数论贪心解法,规避了暴力枚举子序列的高复杂度。对于任意子序列,其权值为 gcd × 元素总和,我们只需枚举所有可能的公约数d,统计数组中所有d的倍数的元素之和sum,则该d对应的最大权值为d × sum,最终取所有结果的最大值即可。由于元素范围a_i≤1e6,直接枚举1到最大元素值,通过调和级数累加倍数和。算法时间复杂度为

O

(

m

a

x

a

log

m

a

x

a

)

O(max_a \\log max_a)

O(maxalogmaxa),完美适配

n

10

5

n≤10^5

n105的大数据约束,简洁高效。

总结

核心逻辑:枚举所有可能的gcd值,计算其倍数元素的总和,取gcd×总和的最大值。 关键操作:统计元素和、枚举公约数、累加对应倍数的元素总和。 效率保障:调和级数复杂度,无需遍历子序列,轻松处理十万级数据。

代码内容

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

#define endl '\\n'
typedef long long ll;
typedef unsigned long long ull;
typedef vector<vector<ll>> vvt;
typedef pair<ll,ll> pll;
const ll N=1;
const ll INF=1e18;
const ll M=1e6+10;
const ll mod=998244353;

void solved()
{
ll n;
cin>>n;
ll ma=0;
vector<ll> a(n);
for(ll i=0;i<n;i++)
{
cin>>a[i];
if(a[i]>ma) ma=a[i];
}
vector<ll> s(ma+1);
for(auto& x:a) s[x]+=x;
ll res=0;
for(ll i=1;i<=ma;i++)
{
ll t=0;
for(ll j=i;j<=ma;j+=i) t+=s[j];
res=max(res,t*i);
}
cout<<res<<endl;
}

int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
ll t=1;
//cin>>t;
while(t) solved();
return 0;
}

赞(0)
未经允许不得转载:171主机测评 » 小红与gcd和sum【牛客tracker & 每日一题】
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址