题解 CF1762B Make Array Good
大家好,我是 CQ-C2024 蒟蒻 CJH。
题意
给定 $n$ 个数 $a_i$,你可以进行下面这个操作至多 $n$ 次(当然也可以一次也不执行),让 $a$ 数组中的每一个数成倍数关系:
- 将 $a_i$ 赋值为 $a_i+x$,其中 $x$ 为一个不超过 $a_i$ 的非负整数,还需要保证修改后的 $a_i \le 10^{18}$。
分析
在 $a_i \sim 2a_i$ 中,必定存一个 $2$ 的整次幂,所以我们只需要将每个 $a_i$ 修改为最小的不小于 $a_i$ 的 $2$ 的整次幂,即可保证两两之间为倍数关系。
看到另外一篇题解是使用的循环来找到这个值,我使用的是更加简洁的数学方法,这个值为:
$$2^{\lceil \log_2 a_i \rceil}$$
所以可以直接用位移和数学函数即可解决问题。
代码
#include<iostream>
#include<cstdio>
#include<cmath>
int n,a[100001];
int main(){
int t;scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
printf("%d\n",n);//每个数都进行一个操作,如果不需要则进行一个加 0 的操作。
for(int i=1;i<=n;i++) printf("%d %d\n",i,(1<<((int)ceil(log2(a[i]))))-a[i]);//用这个式子求解上述的值。
}
return 0;
}

浙公网安备 33010602011771号