Loading

题解:SP8995 LQDCANDY - CANDY

提醒

long long,开 long long,开 long long!重要的事情说三遍。

第一问

Easy,对于长度为 \(n\) 的巧克力,自然需要一个 \(2\) 的非负整数次幂的数,使其为最小的大于等于 \(n\) 的整数,数学语言表示就是:

\[\mathrm{res}=2^{\lfloor\log_2n\rfloor} \]

复杂度 \(O(1)\)

第二问

肯定 \(O(1)\) 解决不了,依照逆天的数据强度,得在 \(\log\) 级别才能通过。

首先有个定理:对于 \(2 \mid n\) 的情况,一定有 \(\mathrm{ans}_{\frac{n}{2}}=\mathrm{ans}_n\)

为什么?

因为切割次数和 \(n\)\(2\) 的关系是无关的。那我们可以一直重赋值 \(n\)\(\dfrac{n}{2}\),直到 \(2\nmid n\) 为止。

对于 \(\rm{res}\) 呢?

\(\rm res\) 也要跟随着 \(n\) 自己除以 \(2\),有点类似分治,不断缩小问题规模,到最后 \(\rm{res}\) 的值就是 \(n\) 的第一问的结果。

题目要我们求切割次数,所以输出 \(\log \rm res\),注意不用取整,\(\rm res\)\(2^i\)

故代码如下:

#include <bits/stdc++.h>
#define rty printf("Yes\n");
#define RTY printf("YES\n");
#define rtn printf("No\n");
#define RTN printf("NO\n");
#define rep(v,b,e) for(int v=b;v<=e;v++)
#define repq(v,b,e) for(int v=b;v<e;v++)
#define rrep(v,e,b) for(int v=b;v>=e;v--)
#define rrepq(v,e,b) for(int v=b;v>e;v--)
#define stg string
#define vct vector
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

void solve() {
  ll n;
  cin >> n;
  ll ans = pow(2, ceil(log2((ll)n)));
  cout << ans << ' ';
  while (!(n % 2)) { n /= 2; ans /= 2; }
  cout << log2(ans) << endl;
}


main() {
	int t; cin >> t; while (t--) solve();
	return 0;
}
posted @ 2024-07-22 11:44  CoutingStars  阅读(11)  评论(0)    收藏  举报