一开始有一个数列{1}。每过一天,将他当天的数列复制一遍,放在数列尾,并在两个数列间用0隔开。将当天新产生的所有数字(包括0)全加1。这个数列的前M项和是多少?
推公式
注意BigInteger类的写法
import java.io.*;
import java.util.*;
import java.math.*;
public class Main{ static BigInteger g[] = new BigInteger[2000]; static BigInteger b2 = new BigInteger("2"); static BigInteger p2[] = new BigInteger[2000]; public static void main(String[] arg){ Scanner cin = new Scanner(System.in); p2[1]= new BigInteger("2");for(int i=2;i<=1000;i++) p2[i]=p2[i-1].multiply(b2); g[1] = new BigInteger("1");for(int i=2;i<=1000;i++) g[i]=g[i-1].multiply(b2).add(p2[i-1]); int T=cin.nextInt(); while ((T--)>0) { BigInteger m = cin.nextBigInteger(); BigInteger ans = new BigInteger("0"); while(m.compareTo(BigInteger.ZERO)==1) {int k=1;while (p2[k+1].subtract(BigInteger.ONE).compareTo(m)<=0) ++k;ans = ans.add(g[k]);m = m.subtract(p2[k].subtract(BigInteger.ONE));if (m.compareTo(BigInteger.ONE)>=0) {m = m.subtract(BigInteger.ONE);ans = ans.add(BigInteger.ONE);}ans = ans.add(m);}System.out.println(ans);} }
}