http://codeforces.com/contest/1166/problem/D
https://www.lucien.ink/archives/433
Given a positive integer m m m, we say that a sequence x 1 , x 2 , … , x n x_1, x_2, \dots, x_n x1,x2,…,xn of positive integers is m m m-cute if for every index i i i such that 2 ≤ i ≤ n 2 \le i \le n 2≤i≤n it holds that x i = x i − 1 + x i − 2 + ⋯ + x 1 + r i x_i = x_{i - 1} + x_{i - 2} + \dots + x_1 + r_i xi=xi−1+xi−2+⋯+x1+ri for some positive integer r i r_i ri satisfying 1 ≤ r i ≤ m 1 \le r_i \le m 1≤ri≤m.
You will be given q q q queries consisting of three positive integers a a a, b b b and m m m. For each query you must determine whether or not there exists an m m m-cute sequence whose first term is a a a and whose last term is b b b. If such a sequence exists, you must additionally find an example of it.
定义 x i = x i − 1 + x i − 2 + ⋯ + x 1 + r i x_i = x_{i - 1} + x_{i - 2} + \dots + x_1 + r_i xi=xi−1+xi−2+⋯+x1+ri , 1 ≤ r i ≤ m 1 \le r_i \le m 1≤ri≤m ,给你 a b m
,判断是否存在一个一个序列 x x x ,假定这个序列的长度为 n n n ,使得 x 1 = a x_1 = a x1=a 且 x n = b x_n = b xn=b 。
规定 2 x = 0 2 ^ {x} = 0 2x=0 ( x < 0 ) (x < 0) (x<0) ,归纳一下,可以发现: (a) x n ( n ≥ 2 ) = 2 n − 2 a + 2 n − 3 r 2 + 2 n − 4 r 3 + ⋯ + 2 r n − 2 + r n − 1 + r n x_{n(n \ge 2)} = 2 ^ {n - 2}a + 2 ^ {n - 3} r_2 + 2 ^ {n - 4} r_3 + \dots + 2r_{n - 2} + r_{n - 1} + r_n\ \tag{a} xn(n≥2)=2n−2a+2n−3r2+2n−4r3+⋯+2rn−2+rn−1+rn (a)
即判断是否存在一个 x n x_n xn 满足 ( a ) (a) (a) 式且 x n = b x_n = b xn=b 。
可以进一步简写一下,如果将 b b b 代入 ( a ) (a) (a) 式,且令: (b) r = 2 n − 3 r 2 + 2 n − 4 r 3 + ⋯ + 2 r n − 2 + r n − 1 + r n r = 2 ^ {n - 3} r_2 + 2 ^ {n - 4} r_3 + \dots + 2r_{n - 2} + r_{n - 1} + r_n \tag{b} r=2n−3r2+2n−4r3+⋯+2rn−2+rn−1+rn(b) 则有: b = 2 n − 2 a + r b = 2 ^ {n - 2}a + r b=2n−2a+r 可以发现忽略 ( b ) (b) (b) 式中的 r n r_n rn 之后,剩下的式子为 r r r 为一个二进制表示,我们可以将 ( b ) (b) (b) 整体减去一个 k k k 从而消掉 r n r_n rn ,这样一来可以表示为 x n = 2 n − 2 ( a + k ) + r x_n = 2 ^ {n - 2}(a + k) + r xn=2n−2(a+k)+r ,令 r r r 的二进制表示为 d n − 3 d n − 4 … d 0 d_{n - 3}d_{n - 4} \dots d_0 dn−3dn−4…d0 ,此时 r i ( i < n ) = k + d n − i − 1 r_{i(i < n)} = k + d_{n - i - 1} ri(i<n)=k+dn−i−1 , r n = k r_n = k rn=k 。
然后暴力输出 x x x 序列即可。
https://pasteme.cn/8173
#include
const int maxn = 54;
typedef long long ll;
ll __pow[maxn] = {1}, r[maxn], a, b, m;
int solve() {
if (a == b) return 1;
for (int n = 2; __pow[n - 2] <= b; n++) {
ll div = b / __pow[n - 2], mod = b % __pow[n - 2];
if (div > a && (div - a < m || (mod == 0 && div - a <= m)) && __pow[n - 2] - 1 >= mod) {
for (int i = 2, bit = n - 3; bit >= 0; i++, bit--) r[i] = (mod >> bit & 1) + div - a;
return n;
}
}
return -1;
}
ll calc(int x, int n) {
if (x > 1 && x < n) {
ll ret = __pow[x - 2] * a;
for (int i = 2; i < x; i++) ret = ret + __pow[x - i - 1] * r[i];
return ret + r[x];
} else return x == 1 ? a : b;
}
int main() {
int q, n;
for (int i = 1; i < maxn; i++) __pow[i] = __pow[i - 1] << 1;
for (scanf("%d", &q); q; q--) {
scanf("%lld%lld%lld", &a, &b, &m);
if (~(n = solve())) {
printf("%d ", n);
for (int i = 1; i <= n; i++) printf("%lld%c", calc(i, n), i == n ? '\n' : ' ');
} else puts("-1");
}
return 0;
}