1-70即可,1-100会爆
题意:给了一个n(1e18),m个数(每个数都是2的若干次mi)。你可以进行若干个操作使得这m个数的其中一个分成两份,问最少进行多少次操作可以使得这些数恰好组成n。
思路:1e18大约是2的六十多次mi,很显然应该在mi上操作。预处理一下2若干次mi的值。然后把n拆成2的多少次mi的若干份,比如10可以拆成23和21两份,然后应该用这m个数的较小值优先填充,如果不够则才需要大的数来拆,步数为不够填充的位置和m第一个能把这一份填充的位置差。每当位数进一,sum/2。
定义一个vis数组用来存。把10拆了,在1和3位置分别都有,让vis在这些位置-1。然后把这m个数换成2的mi存到vis,让vis在这个位置加1。
定义一个sum,每当下标进一,sum/2,用sum加上当前vis的值,用一个ans储存sum是负数一共有多少个位置。答案即为ans(遍历0-70即可,太大会爆)
因为sum要除以2,所以定义成double即可。
#include
#include
#include
#include
#include <string>
#include