Codeforces Round #521 (Div. 3) D. Cutting Out 【二分+排序】

任意门:http://codeforces.com/contest/1077/problem/D

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

Note

The first example is described in the problem statement.

In the second example the only answer is [7,3,1,3][7,3,1,3] and any its permutations. It can be shown that you cannot choose any other array such that the maximum number of copies you can cut out would be equal to 22.

In the third example the array tt can be cut out 55 times.

题意概括:

在长度为N的序列中找出K个元素的子序列,满足这个子序列在序列中最多(子序列 不要求有序,连续);

解题思路:

一开始的思想:记录每种数出现的次数,按照降序排序,高出现次数的补低出现次数的,贪心最大化最小值。(wa,代码实现不好)

二分+排序(其实看到要最大化最小值就应该想到了的。。。)

排序还是记录原N序列的每种数的出现次数,按照降序排序;

二分最低出现的次数,判断条件是以这个最低标准是否能填充满 子序列 K。

AC code:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #define LL long long
 6 using namespace std;
 7 const int MAXN = 1e6+10;
 8 LL sum, mx, x;
 9 int K, N, ct, cnt;
10 int ans[MAXN], ans0, an[MAXN];
11 int l = 1, r;
12 int p[MAXN];
13
14 struct date
15 {
16     int num, t;
17 }a[MAXN];
18
19 bool cmp(date a, date b)
20 {
21     return a.t > b.t;
22 }
23
24 bool judge(int tms)
25 {
26     cnt = 0;
27     for(int i = 1; i <= ct; i++){
28         int tmp = a[i].t;
29         if(tmp < tms) break;        //因为已经排序过了
30         while(tmp >= tms){
31             tmp-=tms;
32             ans[++cnt] = a[i].num;
33         }
34     }
35     return cnt>=K;
36 }
37
38 int main()
39 {
40     scanf("%d%d", &N, &K);
41     r = N;
42     for(int i = 1; i <= N; i++){
43         scanf("%d", &x);
44         if(mx < x) mx = x;
45         p[x]++;
46     }
47     for(int i = 1; i <= mx; i++){
48         if(p[i]){
49             a[++ct].num = i;
50             a[ct].t = p[i];
51         }
52     }
53     sort(a+1, a+1+ct, cmp);
54     int mid;
55     while(l<=r){
56         mid = (l+r)>>1;
57         if(judge(mid)){
58             an[0] = 0;
59             for(int i = 1; i <= cnt; i++){
60                 an[++an[0]] = ans[i];
61                 l = mid+1;
62             }
63         }
64         else r = mid-1;
65     }
66     for(int i = 1; i <= K; i++){
67         printf("%d ", an[i]);
68     }
69     puts("");
70     return 0;
71 }

原文地址:https://www.cnblogs.com/ymzjj/p/9973185.html

时间: 2024-11-07 21:42:29

Codeforces Round #521 (Div. 3) D. Cutting Out 【二分+排序】的相关文章

Codeforces Round #521 (Div. 3) D. Cutting Out

D. Cutting Out 题目链接:https://codeforces.com/contest/1077/problem/D 题意: 给你n个数,现在要你选k个数出来,并且能够从这n个数种选取尽量多的这k个数. 题解: 一开始想的贪心+模拟,然后写崩了... 其实这个题二分一下选几组就好了,因为要选几个数是固定了的,所以我们可以用二分来判断可行性(根据二分的x和每个数出现的次数来判断),即是否可以选够k个数,这个很容易办到. 然后最后统计一下每个数出现的个数,最后无脑选输出答案就行了. 代

Codeforces Round #262 (Div. 2) 460C. Present(二分)

题目链接:http://codeforces.com/problemset/problem/460/C C. Present time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Little beaver is a beginner programmer, so informatics is his favorite subjec

Codeforces Round #470 (Div 2) B 数学 C 二分+树状数组 D 字典树

Codeforces Round #470 B. Primal Sport 数学题,对 x2 和 x1 分解质因子即可. #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b;

Codeforces Round #521 (Div. 3)

题目链接:http://codeforces.com/contest/1077 A.Frog Jumping 解题思路: AC代码: 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 LL T,a,b,k;///差值相减即可 5 int main(){ 6 while(cin>>T){ 7 while(T--){ 8 cin>>a>>b>>k; 9

CodeForces Round #521 (Div.3) C. Good Array

http://codeforces.com/contest/1077/problem/C Let's call an array good if there is an element in the array that equals to the sum of all other elements. For example, the array a=[1,3,3,7]a=[1,3,3,7] is good because there is the element a4=7a4=7 which

Codeforces Round #353 (Div. 2) D. Tree Construction (二分,stl_set)

题目链接:http://codeforces.com/problemset/problem/675/D 给你一个如题的二叉树,让你求出每个节点的父节点是多少. 用set来存储每个数,遍历到a[i]的时候查找比a[i]大的数的位置,然后插入,而父亲就是刚好比a[i]小的数或刚好大的数. 然后讨论是哪一个数. 比如给你3 1 2 ,如图 1的父亲是3 ,2的父亲是1. 那我其实只要找左边或右边出现最晚的数就行了,用pair的first表示a[i],second表示出现的顺序i. 1 #include

Codeforces Round #211 (Div. 2) D题(二分,贪心)解题报告

---恢复内容开始--- 题目地址 简要题意: n个小伙子一起去买自行车,他们有每个人都带了一些钱,并且有公有的一笔梦想启动资金,可以分配给任何小伙子任何数值,当然分配权在我们的手中.现在给出m辆自行车的价格,需要你求出最多可以让多少个小伙子有属于自己的自行车(即自行车不可以两个人共有,只能一个人有),和在满足之前这个条件的情况下,通过最省私人钱的分配,最少需消耗多少私人的资金. 思路分析: 首先考虑,如何分配才是使其中x个小伙子能有自己车的最好分配方法.不难想到,将n个小伙子按个人资金从大到小

Codeforces Round #281 (Div. 2) C. Vasya and Basketball 排序

C. Vasya and Basketball Vasya follows a basketball game and marks the distances from which each team makes a throw. He knows that each successful throw has value of either 2 or 3 points. A throw is worth 2 points if the distance it was made from does

Codeforces Round #344 (Div. 2) E. Product Sum 二分斜率优化DP

E. Product Sum Blake is the boss of Kris, however, this doesn't spoil their friendship. They often gather at the bar to talk about intriguing problems about maximising some values. This time the problem is really special. You are given an array a of