终于有大月赛了哈哈哈
思路
一上来,看着有点像倍增,于是我们就思考:
如果要使用倍增,那么我们应该可以在某些时刻不跳。
但是题目要求每秒钟都必须跳,于是我们就来寻找有没有办法可以让我们想不跳的操作无效。
在多次尝试之后我们发现:
$$2^{n - x} = 2^n - \sum\limits_{i = 1}^{x} 2^{n - i}$$
其中 $x$ 为正整数且 $0 \le x \le n$。
所以这意味着什么呢?我们找到让操作无效的方法了。
我们只需要在每一秒跳之前先看一下,下一步要不要停?如果要停就向反方向跳,否则就分两种情况:
- 如果当前这一步本来就要跳,那就按原计划跳;
- 如果当前这一步本来要停止,那就按上一次本来要跳但是因为前面说的情况想反方向跳的一步的原方向跳。
但是第 $1$ 秒很特殊,因为第一秒没有上一秒,所以只有第 $1$ 秒是不能跳过的,于是我们发现:只要 $n$ 是偶数就无法到达,否则就可以到达。
虽然我们刚刚是用倍增的思路去分析的,但是这道题目很拉胯我们需要求的答案就是 $\lfloor \log_2n + 1 \rfloor$,所以我们并不需要真的在代码里用倍增。
代码
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define elif else if
int n;
int main()
{
scanf("%d", &n);
for (int i = 1, x; i <= n; i++)
{
scanf("%d", &x);
if (x % 2 == 0)
printf("-1\n");
else
printf("%d\n", int(log2(x) + 1));
}
return 0;
}
评测记录:R98630963。