CF1744D 题解

洛谷传送门 & CF 传送门

思路

首先,我们可以看每个 aia_i 中有多少个 22(最多能被几个 22 整除),并添加到 sumsum 里。如果 sumnsum\ge n,那就不需要操作,直接输出 00。否则,我们就要对每个 ii 也进行拆分,我们设 ii 中有 xx22,那我们就可以对 totx+1tot_x+1totitot_i 表示有 ii22 的数的个数)。记录下来以后,我们肯定是 22 多的先操作,直到满足要求为止。时间复杂度为 n+lognn+\log n,足以通过。

代码

# include <bits/stdc++.h>
using namespace std;
int t, n, x, sum, a[20], tot;
int f () {
	cin >> n;
	memset (a, 0, sizeof a); //多组数据要清空
	tot = sum = 0; //多组数据要清零
	for (int i = 1; i <= n; ++ i) {
		cin >> x;
		while (! (x & 1)) //拆 a[i]
			x >>= 1, ++ sum;
		x = i;
		while (! (x & 1)) 拆 i
			x >>= 1, ++ tot;
		++ a[tot];
		tot = 0;
	}
	if (sum >= n)
		return 0;
	for (int i = 19; i; -- i) { // 倒着枚举,2 多的先操作
		x = sum + a[i] * i;
		if (x >= n) //满足要求
			return tot + (n - sum + i - 1) / i;
		tot += a[i], sum = x;
	}
	return -1;
}
int main () {
	cin >> t;
	while (t --)
		cout << f () << '\n';
	return 0;
}
posted @ 2023-08-18 15:42  Vitamin_B  阅读(9)  评论(0)    收藏  举报  来源