import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int t = in.nextInt();
        for (int tp = 1;tp <= t;++tp) {
            int n = in.nextInt();
            double m = in.nextDouble();
            int ans = 0;
            while (n != 0) {
                ans += n*10 + Math.min(10*(m-1)*n,1000);
                n /= 2;
            }
            System.out.println(ans);
        }
    }
}

这一道题原题模拟就可以过了,比较简单,时间复杂度是O(logn)的。但我在其中想了一下数学公式,企图用O(1)的方式解决,但是因为这里有个中间比较过程(min),所以还是只能用模拟。不过我推出了一个比较优美的公式和几个结论,在这里记录一下吧

  1. 整数除法 q/m/n = q/(mn),我是把q写成mk+r然后一步一步慢慢推导的。所以可以得到q/4 = q/2/2 = q>>1
  2. N + \lfloor\frac{N}{2}\rfloor + \lfloor\frac{N}{4}\rfloor + \lfloor\frac{N}{8}\rfloor + ...+0 = \sum_{i=0}^{b} \lfloor \frac{N}{2^{i}}\rfloor = 2N-popCount(n),其中b为N二进制形式的长度,popCount(N)为N的二进制形式中1的个数。#牛客AI配图神器#