Codeforces Round #766 (Div. 2) D. Not Adding 数学gcd

传送门

目录

题意:

给你一个长度为 n n n的数组,你每次可以选择其中的两个数,如果他们的 g c d gcd gcd在数组中没有出现那么就可以加在数组后面构成一个新的数组,问数组最长是多少。

2 ≤ n ≤ 1 e 6 , 1 ≤ a i ≤ 1 e 6 2\le n\le 1e6,1\le a_i\le 1e6 2n1e6,1ai1e6

思路:

c n t [ i ] cnt[i] cnt[i]表示包含因子 i i i的数有多少个,但是想要判断两个数的 g c d = = i gcd==i gcd==i只靠 c n t [ i ] > 1 cnt[i]>1 cnt[i]>1是不够的,因为不能保证其中两个数的最大公因数是 i i i,但是我我们如果枚举包含以 i i i为因子的数 j j j,如果存在 c n t [ i ] = = c n t [ j ] cnt[i]==cnt[j] cnt[i]==cnt[j],那么一定不存在两个数的最大公因数是 i i i,因为这个时候这些数最大公因数是 j j j。当不存在上述情况且有两个 x , y x,y x,y满足 c n t [ x ] > 0 , c n t [ y ] > 0 cnt[x]>0,cnt[y]>0 cnt[x]>0,cnt[y]>0,那么此时这两个集合中的数最大公因数一定是 i i i,直接 n l o g n nlogn nlogn求即可。

#include<bits/stdc++.h>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define Mid (tr[u].l+tr[u].r>>1)
#define pb push_back
using namespace std;

const int N=1000260,INF=0x3f3f3f3f,mod=1e9+7;
typedef long long LL;
typedef pair<int,int> PII;

int n;
int a[N],mp[N],cnt[N];
int gc[N];

void solve() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
        mp[a[i]]=1; cnt[a[i]]=1;
    }
    int ans=0;
    for(int i=1;i<=1e6;i++) {
        for(int j=i+i;j<=1e6;j+=i) {
            cnt[i]+=cnt[j];
        }
    }
    for(int i=1;i<=1e6;i++) {
        int flag=cnt[i]>0;
        for(int j=i+i;j<=1e6;j+=i) {
            if(cnt[i]==cnt[j]) flag=0;
        }
        ans+=flag;
    }
    printf("%d\n",ans-n);
}

int main() {
	int _=1;
	while(_--) {
		solve();
	}

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值