1. 程式人生 > >Codeforces Round #521 (Div. 3) D - Cutting Out(二分答案)

Codeforces Round #521 (Div. 3) D - Cutting Out(二分答案)

D. Cutting Out

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an array ss consisting of nn integers.

You have to find any array tt of length kk such that you can cut out maximum number of copies of array tt from array ss.

Cutting out the copy of tt means that for each element titi of array tt you have to find titi in ss and remove it from ss. If for some titi you cannot find such element in ss, then you cannot cut out one more copy of tt. The both arrays can contain duplicate elements.

For example, if s=[1,2,3,2,4,3,1]s=[1,2,3,2,4,3,1] and k=3k=3 then one of the possible answers is t=[1,2,3]t=[1,2,3]. This array tt can be cut out 22 times.

  • To cut out the first copy of tt you can use the elements [1,2––,3,2,4,3––,1––][1,2_,3,2,4,3_,1_] (use the highlighted elements). After cutting out the first copy of tt the array ss can look like [1,3,2,4][1,3,2,4].
  • To cut out the second copy of tt you can use the elements [1––,3––,2––,4][1_,3_,2_,4]. After cutting out the second copy of tt the array ss will be [4][4].

Your task is to find such array tt that you can cut out the copy of tt from ss maximum number of times. If there are multiple answers, you may choose any of them.

Input

The first line of the input contains two integers nn and kk (1≤k≤n≤2⋅1051≤k≤n≤2⋅105) — the number of elements in ss and the desired number of elements in tt, respectively.

The second line of the input contains exactly nn integers s1,s2,…,sns1,s2,…,sn (1≤si≤2⋅1051≤si≤2⋅105).

Output

Print kk integers — the elements of array tt such that you can cut out maximum possible number of copies of this array from ss. If there are multiple answers, print any of them. The required array tt can contain duplicate elements. All the elements of tt (t1,t2,…,tkt1,t2,…,tk) should satisfy the following condition: 1≤ti≤2⋅1051≤ti≤2⋅105.

Examples

input

Copy

7 3
1 2 3 2 4 3 1

output

Copy

1 2 3 

input

Copy

10 4
1 3 1 3 10 3 7 7 12 3

output

Copy

7 3 1 3

input

Copy

15 2
1 2 1 1 1 2 1 1 2 1 2 1 1 1 1

output

Copy

1 1 

 

題意:

給你長度為n的序列,讓你從中挑k個數組成序列ans,使得ans序列在原序列中出現次數最多。這裡不用管順序,序列是無序的。

1 2 3 2 4 3 1

出現次數最多的序列是[1,2,3]

解析:

直接二分答案,答案要求最大化出現次數,那麼我們就二分次數mid,把出現次數>=mid的數都加進答案序列,看這個

序列最終能不能>=k

一般思維題、構造題,使你構造一個XXX來最大化或最小化答案,並且未知量只有這個答案,

那麼我們可以直接二分這個答案使所有條件已知,來嘗試構造這個序列,能不能成功.

思維題二分的一般問題都是最大化/最小化某一個值,尤其是最大化最小值/最小化最大值

還有就是最大/小化某一個值來構造序列

#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
const int MAXN = 2e5+100;

int a[MAXN];
int ans[2][MAXN];
int to,k;
bool check(int x,int now)
{
    int cnt=0;
    for(int i=1;i<=to;i++)
    {
        if(a[i]>=x)
        {
            int tmp=a[i]/x;
            for(int j=0;j<tmp;j++) ans[now][cnt++]=i;
        }
        if(cnt>=k) return true;
    }
    return false;
}

int main()
{
    int n;
    scanf("%d%d",&n,&k);

    for(int i=1;i<=n;i++)
    {
        int tmp;
        scanf("%d",&tmp);
        a[tmp]++;
        to=max(to,tmp);
    }
    int l=1;
    int r=n;
    int now=0;
    while(l<r)
    {
        int mid=(l+r)>>1;
        if(check(mid,now^1)) now=now^1,l=mid+1;
        else r=mid;
    }
    if(check(l,now^1)) now=now^1;
    for(int i=0;i<k;i++)
    {
        if(i==0) printf("%d",ans[now][i]);
        else printf(" %d",ans[now][i]);
    }
    printf("\n");
}