51nod 1616 最小集合(枚举倍数)

分析:也就是取任意多个数,它们的最大公约数都在这个集合里。考虑到ai比较小,可以枚举小于a中最大值的所有数,判断是否为其中若干个数的gcd。记c[k]为a中k的倍数的个数,然后枚举k的倍数i*k,c[i]<2直接跳过,如果c[i*k]==c[k],说明k的那些倍数也同时是i*k的倍数,k就可以不在集合中,反之,如果任意i,c[i*k]<c[k],说明存在一个倍数和其它k的倍数的gcd是k,所以k一定在集合中。两次枚举倍数,复杂度为O(nlogn)。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 const int maxn=1e6+5;
 6 bool In_set[maxn];
 7 int count_multiple[maxn];
 8 int main(){
 9     int n,ans=0,a;
10     scanf("%d",&n);
11     ans=n;
12     memset(In_set,0,sizeof(In_set));
13     memset(count_multiple,0,sizeof(count_multiple));
14     for(int i=0;i<n;i++){
15         scanf("%d",&a);
16         if(In_set[a])ans--;
17         In_set[a]=true;
18     }
19     for(int i=1;i<maxn;i++){
20         //if(In_set[i])continue;
21         for(int j=i;j<maxn;j+=i){
22             if(In_set[j])
23                 count_multiple[i]++;
24         }
25     }
26     for(int i=1;i<maxn;i++){
27         if(In_set[i]||count_multiple[i]<2)continue;
28         bool ok=true;
29         for(int j=2*i;j<maxn;j+=i){
30             if(count_multiple[j]==count_multiple[i]){
31                 ok=false;break;
32             }
33         }
34         if(ok)
35             ans++;
36     }
37     cout<<ans<<endl;
38     return 0;
39 }
时间: 2024-10-14 15:14:25

51nod 1616 最小集合(枚举倍数)的相关文章

51nod 1616 最小集合

基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 A君有一个集合. 这个集合有个神奇的性质. 若X,Y属于该集合,那么X与Y的最大公因数也属于该集合. 但是他忘了这个集合中原先有哪些数字. 不过幸运的是,他记起了其中n个数字. 当然,或许会因为过度紧张,他记起来的数字可能会重复. 他想还原原先的集合. 他知道这是不可能的-- 现在他想知道的是,原先这个集合中至少存在多少数. 样例解释: 该集合中一定存在的是{1,2,3,4,6} Input 第一

1616 最小集合 51NOD(辗转相处求最大公约数+STL)

1616 最小集合 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 A君有一个集合. 这个集合有个神奇的性质. 若X,Y属于该集合,那么X与Y的最大公因数也属于该集合. 但是他忘了这个集合中原先有哪些数字. 不过幸运的是,他记起了其中n个数字. 当然,或许会因为过度紧张,他记起来的数字可能会重复. 他想还原原先的集合. 他知道这是不可能的-- 现在他想知道的是,原先这个集合中至少存在多少数. 样例解释: 该集合中一定存在的是{1,2,3,4,6

51Nod - 1098 最小方差

51Nod - 1098 最小方差 若x1,x2,x3......xn的平均数为k. 则方差s^2 = 1/n * [(x1-k)^2+(x2-k)^2+.......+(xn-k)^2] . 方差即偏离平方的均值,称为标准差或均方差,方差描述波动程度. 给出M个数,从中找出N个数,使这N个数方差最小. Input 第1行:2个数M,N,(M > N, M <= 10000) 第2 - M + 1行:M个数的具体值(0 <= Xi <= 10000) Output 输出最小方差 *

51nod 1065 最小正子段和

题目链接:51nod 1065 最小正子段和 房教说用前缀和做,然后看了别人博客懂了后就感觉,这个真有意思... 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = 50001; 6 const int inf = 0x3f3f3f3f; 7 pair<long long, int> sum[N]; 8 int

集合枚举

采用二进制进行集合枚举: 例如可以用二进制表示集合{2,3,6,1,7},二进制第i位对应集合第i个元素,1代表在,0代表不在集合中.上述集合全集为s=111112=31,例如子集A={2,1,7}可以表示为: 100112=25.而B={2,3,6,7}可以表示为:111012=23,.下面利用位运算完成对集合的运算: A&B=10011&11101=10001={2,7} A|B=10011|11101=11111={2,3,6,1,7} A^B=01110={3,6,1}; 一般用A

51nod 1352:集合计数

1352 集合计数 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 给出N个固定集合{1,N},{2,N-1},{3,N-2},...,{N-1,2},{N,1}.求出有多少个集合满足:第一个元素是A的倍数且第二个元素是B的倍数. 提示: 对于第二组测试数据,集合分别是:{1,10},{2,9},{3,8},{4,7},{5,6},{6,5},{7,4},{8,3},{9,2},{10,1}.满足条件的是第2个和第8个. Input 第1行:1

There is a war (hdu 2435 最小割+枚举)

There is a war Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 970    Accepted Submission(s): 277 Problem Description There is a sea. There are N islands in the sea. There are some directional

(简单) POJ 3279 Fliptile,集合枚举。

Description Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He has arranged a brainy activity for cows in which they manipulate an M × N grid (1 ≤ M ≤ 15; 1 ≤ N ≤ 15) of square tiles, each of which is co

51nod 1283 最小周长

一个矩形的面积为S,已知该矩形的边长都是整数,求所有满足条件的矩形中,周长的最小值.例如:S = 24,那么有{1 24} {2 12} {3 8} {4 6}这4种矩形,其中{4 6}的周长最小,为20. Input 输入1个数S(1 <= S <= 10^9). Output 输出最小周长. Input示例 24 Output示例 20水题.. #include <algorithm> #include <iostream> #include <cstring