Link
思维
题意
给你一个数列
T
T
T,要你构造一个数列
A
A
A 满足:
即满足
A
i
A_i
Ai 严格递增并
c
t
z
(
A
i
)
=
T
i
ctz(A_i) = T_i
ctz(Ai)=Ti 。
其中
c
t
z
(
A
i
)
ctz(A_i)
ctz(Ai) 是
A
i
A_i
Ai 二进制下的后导零的数量,例如
c
t
z
(
(
10100
)
2
)
=
2
ctz((10100)_2) = 2
ctz((10100)2)=2, 求
A
N
A_N
AN 的最小值。
思路
比如一个数 x x x 的 c t z ( x ) = 5 ctz(x) = 5 ctz(x)=5,相当于它可以被 2 5 2^5 25 整除但不能被 2 6 2^6 26 整除,所以对于 A i A_i Ai, 我们要求它满足以下3个条件
- A i > A i − 1 A_i > A_{i-1} Ai>Ai−1
- A i % ( 1 < < T i ) = 0 A_i \% (1<<T_i) = 0 Ai%(1<<Ti)=0
- A i % ( 1 < < ( T i + 1 ) ) ! = 0 A_i \% (1<<(T_i+1)) != 0 Ai%(1<<(Ti+1))!=0
先考虑满足前两个条件的最小的数,设
q
=
1
<
<
T
i
q = 1<<T_i
q=1<<Ti ,则
A
i
=
(
A
i
−
1
/
q
+
1
)
×
q
A_i = (A_{i-1}/q + 1)\times q
Ai=(Ai−1/q+1)×q
类似向上取整的过程。
对于这个
A
i
A_i
Ai ,如果它能被 q*2 整除,再加上q就可以了。
代码
void solve() {
int n;
cin >> n;
int x;
ll ans = 0;
while(n--) {
cin >> x;
ll q = 1ll << x;
ans = (ans / q + 1) * q;
if(((ans >> x) & 1) == 0) ans += q;
}
cout << ans << endl;
}