Codeforce GCD Table STL中的multisets

GCD Table
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

The GCD table G of size n × n for an array of positive integers a of length n is defined by formula

Let us remind you that the greatest common divisor (GCD) of two positive integers x and y is the greatest integer that is divisor of both x and y, it is denoted as . For example, for array a = {4, 3, 6, 2} of length 4 the GCD table will look as follows:

Given all the numbers of the GCD table G, restore array a.

Input

The first line contains number n (1 ≤ n ≤ 500) — the length of array a. The second line contains n2 space-separated numbers — the elements of the GCD table of G for array a.

All the numbers in the table are positive integers, not exceeding 109. Note that the elements are given in an arbitrary order. It is guaranteed that the set of the input data corresponds to some array a.

Output

In the single line print n positive integers — the elements of array a. If there are multiple possible solutions, you are allowed to print any of them.

Examples
Input
4
2 1 2 3 4 3 2 6 1 1 2 2 1 2 3 2
Output
4 3 6 2
Input
1
42
Output
42 
Input
2
1 1 1 1
Output
1 1 


这题的思路就是,向这n^2中不断的找最大的数,然后与前面已经按照同样方法选出来的数求最大公约数,并在后面的数中抹去,一直循环到选出n个数为之。

这题刚开始用vector做的一直超时,其实是可以用multisets来做更简单,因为multisets自带排序功能,(你可以试着输出multisets中的元素)他是按照从小到大的自然顺序存放数据的。

具体这个multisets内部是怎么回事,这里就不多说,其实用的时候只需要知道他是基于红黑二叉树实现的排序,执行查找、插入、删除等操作的时间复杂度为O(logn)就可以了。


#include<iostream>
#include<cstdio>
#include<set>   ///这是它的头文件
#include<algorithm>
using namespace std;
static int gcd(int x, int y) {return y==0?x:gcd(y,x%y);}  ///求最大公约数
bool cmp(const int &x,const int &y){
    return x>y ;
}
int main() {
    int n ;
    while(~scanf("%d",&n)){
        multiset<int> q ;
        q.clear() ;
        int a ;
        for(int i=0;i<n*n;i++){
            scanf("%d",&a);
            q.insert(a) ;
        }
        multiset<int>::iterator it;  ///迭代器,取数必须用
        int arry[5005];
        int c = 0 ;
        for(int i=0;i<n;i++){
             it = q.end() ;
            it-- ;
             arry[c]= *it ;
             q.erase(it) ;
             c++;
             for(int j =0 ;j<c-1;j++){
                 int com = gcd(arry[j],arry[c-1]) ;
                 it = q.lower_bound(com);
                 q.erase(it);
                 it = q.lower_bound(com);
                 q.erase(it);
             }
        }
        for(int i=0;i<c-1;i++){
           printf("%d ",arry[i]);
        }printf("%d\n",arry[c-1]);
    }
    return 0;
}

下面也附上我超时的vector代码,毕竟也写了好久。

唯一的参考价值就是,包含了一些vector的部分用法。

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
static int gcd(int x, int y) {return y==0?x:gcd(y,x%y);}
bool cmp(const int &x,const int &y){
    return x>y ;
}
int main() {
    int n ;
    while(~scanf("%d",&n)){
        vector<int> q ;
        q.clear() ;
        int a ;
        for(int i=0;i<n*n;i++){
            scanf("%d",&a);
            q.push_back(a) ;
        }
        //sort(q.begin(),q.end(),cmp);
        sort(q.begin(),q.end());
//        vector<int>::iterator it;
//        for(it=q.begin();it!=q.end();it++){
//            printf("%d\n",*it);
//        }

        int arry[5005];
        int c = 0 ;
        for(int i=0;i<n;i++){
             arry[c]= q.back();
             q.erase(q.end()-1) ;
             c++;
             for(int j =0 ;j<c-1;j++){
                 int com = gcd(arry[j],arry[c-1]) ;
                 int k = lower_bound(q.begin(),q.end(),com)-q.begin();
                 q.erase(q.begin()+k);
                 q.erase(q.begin()+k);
             }
        }
        for(int i=0;i<c-1;i++){
           printf("%d ",arry[i]);
        }printf("%d\n",arry[c-1]);
    }
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值