题解 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;
}
posted @ 2022-12-21 10:21  Chen_Jinhui  阅读(13)  评论(0)    收藏  举报  来源