10.02T5 枚举因数+纵向思考

Description

Input

  输入文件为二行,第一行为N,第二行为N个数Ai。

Output

一个数即答案

Sample Input

5 5 6 7 10 21

Sample Output

17

Hint


【数据规模与约定】
 
 
 
 
 
题解:
首先最暴力的做法肯定就是枚举n^2条边然后进行排序,接着我们再用kruskal求一遍最大生成树就可以了
然后我们看部分数据怎么处理,首先我们知道如果ai是有重复的话实际上就是一样的,首先可以去重在剩下的数字里面进行暴力
接下来我们考虑一个问题,如果一条边的权值是 i 那么它一定是由k1*i,k2*i 的点之间的。
显然按照题目的数据范围我们可以暴力统计每一个数字的所有因数,然后考虑在尽量大的相同的因子的两个数之间连边
所以这里我们可以使用vector进行统计,vector i 存储的是因数有 i 的全部数字的编号,然后跑kruskal的时候我们可以从大到小枚举这个 i 的编号连边,用并查集维护一下,输出答案就可以了
code:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 using namespace std;
 5 vector<int>fac[100000];
 6 int max0,fa[100005],n,a[100005];
 7 int read(){
 8     int f=1,x=0;
 9     char c=getchar();
10     while(!isdigit(c)){
11         if(c=='-')f=-1;
12         c=getchar();
13     }
14     while(isdigit(c)){
15         x=(x<<3)+(x<<1)+c-'0';
16         c=getchar();
17     }
18     return x*f;
19 }
20 
21 int find(int x){
22     if(x!=fa[x])return fa[x]=find(fa[x]);
23     return fa[x];
24 }
25 void merge(int x,int y){
26     int f1=find(x),f2=find(y);
27     if(f1!=f2){
28         fa[f1]=f2;
29     }
30 }
31 void kruskal(){
32     long long ans=0;
33     int cnt=0;
34     for(int i=max0;i>=1;i--){
35         for(int j=1;j<fac[i].size();j++){
36             int x=fac[i][j],y=fac[i][j-1];
37             if(find(x)!=find(y)){
38                 merge(x,y);
39                 ans+=i;
40                 if(cnt==n-1){
41                     cout<<ans;
42                     exit(0);
43                 }    
44             }
45         }
46     }
47     cout<<ans;
48 }
49 int main(){
50     n=read();
51     for(int i=1;i<=n;i++){
52         a[i]=read();
53         fa[i]=i;
54         max0=max(max0,a[i]);
55     }
56     for(int i=1;i<=n;i++){
57         for(int j=1;j*j<=a[i];j++){//暴力分解每一个数字的因子 
58             if(a[i]%j==0){//如果可以整除就代表可以组成gcd 
59                 fac[j].push_back(i);//那么这个数字的倍数里面就会有这个数字 
60                 fac[a[i]/j].push_back(i);//同样这个数字因子被除了之后的里面也会有这个数字 
61             }
62         }
63     }
64     kruskal();
65 }

over

原文地址:https://www.cnblogs.com/saionjisekai/p/9762922.html