• 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;
    }
    
    
  • 相关阅读:
    OpenJDK源码研究笔记(十二):JDBC中的元数据,数据库元数据(DatabaseMetaData),参数元数据(ParameterMetaData),结果集元数据(ResultSetMetaDa
    Java实现 LeetCode 257 二叉树的所有路径
    Java实现 LeetCode 257 二叉树的所有路径
    Java实现 LeetCode 257 二叉树的所有路径
    Java实现 LeetCode 242 有效的字母异位词
    Java实现 LeetCode 242 有效的字母异位词
    Java实现 LeetCode 242 有效的字母异位词
    Java实现 LeetCode 241 为运算表达式设计优先级
    Java实现 LeetCode 241 为运算表达式设计优先级
    Java实现 LeetCode 241 为运算表达式设计优先级
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/16658693.html
Copyright © 2020-2023  润新知