Codeforces Round #441 (Div. 2) D

本文解析了一道关于计算团队价值总和的问题,通过巧妙的数学推导简化复杂度,利用组合数学和递归思想实现了高效算法。文章详细介绍了如何通过预处理因数个数并结合组合数性质来解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

给你n个数
然后定义一个团队为选出若干个数,使得他们gcd不为1
然后一个团队的价值为,他们所有数的gcd乘上他们的人数
然后要你算出所有有可能的团队的和

题解

挺神的一道题。。反正我是不怎么会了。。要嘎爷爷带飞
然后怎么做呢?
我们考虑答案是怎么算的:

Ans=igcdigcd

我们用一个数组,sum[i]表示gcd为i个序列长度和个数的总和
不难知道,答案就是
isum[i]

那么怎么算出这个sum[i]呢
先假设一个有公因数i的情况吧。。
我们定义,cnt[i]为有因数i的个数
然后可以得到
sum[i]=u=1cnt[i]Cucnt[i]u

sum[i]=u=1cnt[i]cnt[i]!(cnt[i]u)!(u1)!

把一个cnt[i]提出来
sum[i]=u=1cnt[i]cnt[i](cnt[i]1)!(cnt[i]u)!(u1)!

我们可以发现,右式又形成了一个组合数。。公式太麻烦,不想打了
于是用二项式定义化简可得
sum[i]=cnt[i]2cnt[i1]

然后当然,这有许多多算的,就是说i吧i的倍数也算上了,所以要减去他的倍数

于是就做完了
CODE:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
const LL MOD=1e9+7;
const LL N=200005;
const LL M=1000005;
LL n;
LL s[N];
LL cnt[M];//这个因数有多少个人有
bool in[M];
LL f[M];
LL get (LL x,LL y)
{
    if (y==1) return x;
    if (y==0) return 1;
    LL lalal=get(x,y/2);
    lalal=lalal*lalal%MOD;
    if (y&1) lalal=lalal*x%MOD;
    return lalal;
}
LL dfs (LL x)
{
    if (in[x]==true) return f[x];
    in[x]=true;
    if (cnt[x]==0) {f[x]=0;return 0;}
    LL lalal=0;
    for (LL i=2;i*x<=1000000;i++)
    {
        lalal=lalal+dfs(i*x);
        if (lalal>=MOD) lalal-=MOD;
    }
    f[x]=((cnt[x]*get(2,cnt[x]-1)%MOD-lalal)%MOD+MOD)%MOD;
    return f[x];
}
int main()
{
    memset(in,false,sizeof(in));
    scanf("%lld",&n);
    for (LL u=1;u<=n;u++)   scanf("%lld",&s[u]);
    for (LL u=1;u<=n;u++)
    {
        for (LL i=2;i*i<=s[u];i++)
            if (s[u]%i==0)
            {
                cnt[i]++;
                if (i*i!=s[u]) cnt[s[u]/i]++;
            }
        cnt[s[u]]++;
    }
    for (LL u=2;u<=1000000;u++) dfs(u);
    LL ans=0;
    for (LL u=2;u<=1000000;u++) ans=(ans+u*f[u]%MOD)%MOD;
    printf("%lld\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值