CF1453D Checkpoints(期望)
Gildong is developing a game consisting of 𝑛n stages numbered from 11 to 𝑛n. The player starts the game from the 11-st stage and should beat the stages in increasing order of the stage number. The player wins the game after beating the 𝑛n-th stage.
There is at most one checkpoint on each stage, and there is always a checkpoint on the 11-st stage. At the beginning of the game, only the checkpoint on the 11-st stage is activated, and all other checkpoints are deactivated. When the player gets to the 𝑖i-th stage that has a checkpoint, that checkpoint is activated.
For each try of a stage, the player can either beat the stage or fail the stage. If they beat the 𝑖i-th stage, the player is moved to the 𝑖+1i+1-st stage. If they fail the 𝑖i-th stage, the player is moved to the most recent checkpoint they activated, and they have to beat the stages after that checkpoint again.
For example, assume that 𝑛=4n=4 and the checkpoints are on the 11-st and 33-rd stages. The player starts at the 11-st stage. If they fail on the 11-st stage, they need to retry the 11-st stage because the checkpoint on the 11-st stage is the most recent checkpoint they activated. If the player beats the 11-st stage, they're moved to the 22-nd stage. If they fail it, they're sent back to the 11-st stage again. If they beat both the 11-st stage and the 22-nd stage, they get to the 33-rd stage and the checkpoint on the 33-rd stage is activated. Now whenever they fail on the 33-rd stage, or the 44-th stage after beating the 33-rd stage, they're sent back to the 33-rd stage. If they beat both the 33-rd stage and the 44-th stage, they win the game.
Gildong is going to build the stages to have equal difficulty. He wants you to find any series of stages and checkpoints using at most 20002000 stages, where the expected number of tries over all stages is exactly 𝑘k, for a player whose probability of beating each stage is exactly 1212.
Input
Each test contains one or more test cases. The first line contains the number of test cases 𝑡t (1≤𝑡≤501≤t≤50).
Each test case contains exactly one line. The line consists of a single integer 𝑘k (1≤𝑘≤10181≤k≤1018) — the expected number of tries over all stages Gildong wants to set for a player whose probability of beating each stage is exactly 1212.
Output
For each test case, print −1−1 if it's impossible to construct such a series of stages and checkpoints using at most 20002000 stages.
Otherwise, print two lines. The first line should contain a single integer 𝑛n (1≤𝑛≤20001≤n≤2000) – the number of stages. The second line should contain 𝑛n integers, where the 𝑖i-th integer represents whether the 𝑖i-th stage has a checkpoint. The 𝑖i-th integer should be 00 if the 𝑖i-th stage doesn't have a checkpoint, and 11 if it has a checkpoint. Note that the first integer must be 11 according to the description.
Example
input
Copy
4
1
2
8
12
output
Copy
-1
1
1
4
1 1 1 1
5
1 1 0 1 1
首先看一眼样例,注意到k = 1的情况。这比较好理解,因为对于这一个stage,要么直接通过,要么死一次通过,要么死两次...求一下期望就会发现答案确实是2。然后,如果把每个存档点以及其后面若干个0看作是一段的话,会发现段与段之间对于期望的计算是独立的。因为如果在一段的某个0寄了,回到的是这一段的开始,与之前的段无关。因此考虑如何计算一段的贡献。设一段中有一个1,后面跟着连续k个0的期望是\(E_k\),现在需要计算\(E_{k+1}\),相当于在原来的段后面加上一个0。当走了k个0后,如果能顺利通过新加的这个0,那么对于期望的贡献是\(\frac{1}{2}\times (E_k+1)\),这里直接把\(E_k\)当做一个确定的尝试的次数来计算。如果死一次后通过新加的这个0,那么对于期望的贡献是\(\frac{1}{2^2}\times 2\times(E_k+1)\),这里乘2是因为总共尝试了两倍的\(E_k+1\)...依此类推,死n次后通过新加的0对于期望的贡献是\(\frac{1}{2^{n - 1}}\times (n - 1)\times (E_k+1)\),求一下和会发现如下规律:\(E_{k+1}=2(E_k+1)\),再根据该递推式可得\(E_k=2^{k+2}-2\)。因此,输入的k为奇数可以直接输入-1(因为若干个段的期望和一定是偶数),k为偶数则迭代求解,从最长的段不断开始尝试,直到k减为0(类似倍增)。
#include <bits/stdc++.h>
#define pb push_back
#define ll long long
using namespace std;
void solve() {
ll k;
cin >> k;
vector<ll> ans;
if(k & 1) {
puts("-1");
return;
}
ll b = 61;
ll sum = 0;
while(k) {
if(b < 0) {
puts("-1");
return;
}
ll tmp = (1ll << (b + 2)) - 2;//这里必须要写1ll
if(tmp <= k) {
for(ll i = 1; i <= k / tmp; i++) {
ans.pb(b);
sum += (b + 1);
}
k %= tmp;
}
b--;
}
if(sum > 2000) {
puts("-1");
return;
}
cout << sum << endl;
for(auto x : ans) {
cout << 1 << " ";
for(int i = 1; i <= x; i++) cout << 0 << " ";
}
cout << endl;
}
int main() {
int T = 1;
cin >> T;
while(T--) {
solve();
}
return 0;
}