自学内容网 自学内容网

【Codeforces】CF 2019C

Cards Partition

#数论 #枚举 #鸽巢定理

题目描述

You have some cards. An integer between 1 1 1 and n n n is written on each card: specifically, for each i i i from 1 1 1 to n n n, you have a i a_i ai cards which have the number i i i written on them.

There is also a shop which contains unlimited cards of each type. You have k k k coins, so you can buy at most k k k new cards in total, and the cards you buy can contain any integer between 1 \mathbf{1} 1 and n \mathbf{n} n, inclusive.

After buying the new cards, you must partition all your cards into decks, according to the following rules:

  • all the decks must have the same size;
  • there are no pairs of cards with the same value in the same deck.

Find the maximum possible size of a deck after buying cards and partitioning them optimally.

输入格式

Each test contains multiple test cases. The first line contains the number of test cases t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1t104). The description of the test cases follows. The first line of each test case contains two integers n n n, k k k ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \leq n \leq 2 \cdot 10^5 1n2105, 0 ≤ k ≤ 1 0 16 0 \leq k \leq 10^{16} 0k1016) — the number of distinct types of cards and the number of coins. The second line of each test case contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an ( 0 ≤ a i ≤ 1 0 10 0 \leq a_i \leq 10^{10} 0ai1010, ∑ a i ≥ 1 \sum a_i \geq 1 ai1) — the number of cards of type i i i you have at the beginning, for each 1 ≤ i ≤ n 1 \leq i \leq n 1in. It is guaranteed that the sum of n n n over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2105.

输出格式

For each test case, output a single integer: the maximum possible size of a deck if you operate optimally.

样例 #1

样例输入 #1

9
3 1
3 2 2
5 4
2 6 1 2 4
2 100
1410065408 10000000000
10 8
7 4 6 6 9 3 10 2 8 7
2 12
2 2
2 70
0 1
1 0
1
3 0
2 1 2
3 1
0 3 3


样例输出 #1

2
3
1
7
2
2
1
1
2

解题思路

首先我们要把 n n n个数平均分为大小为 i i i组的几组,并且每一组内的数字都要不同,容易想到鸽巢定理,能分多大的组取决出现次数最多的那个数。

因此我们只需要枚举 i i i,然后看看能不能用 k k k以内的个数来填充,使得出现次数最多的那个数小于组的个数,并且满足 [ i   ∣ ( s u m + k ) ] [i \ |(sum + k)] [i (sum+k)],其中这里的 s u m sum sum表示全部的个数和。

代码

const int N = 2e5 + 10;
 
void solve() {
int n, k;
std::cin >> n >> k;
 
std::vector<int>a(n + 1);
int s = 0;
for (int i = 1; i <= n; ++i) {
std::cin >> a[i];
s += a[i];
}
 
int maxx = *std::max_element(a.begin() + 1, a.end());
 
int ans = 0;
for (int i = 1; i <= n; i++) {
if (k < (s + k) % i) continue;
 
if (maxx * i <= s + k - (s + k) % i) {
ans = std::max(ans, i);
}
}
 
std::cout << ans << "\n";
 
}
 
signed main() {
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
 
int t = 1;
std::cin >> t;
 
while (t--) {
solve();
}
}

原文地址:https://blog.csdn.net/Antonio915/article/details/142720182

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!