It's a sequence, so you could look on the right encyclopedia, OEIS - Sum of two distinct powers of 2, to find every info you need.
You'll find algorithms too. Here's a Java translation of one of them.
for (int j = 0; j < t; j++) {
long n = scan.nextInt();
if (n < 1954) {
nthLongTwoBitSets(n);
} else {
nthBigIntegerTwoBitSets(n);
}
}
r
and i
are the index of the two set bits.
If you have to multiply or divide for a power of 2, you can use the the bit shift operators to speed things up.
Once the number became to big for a long
, you have to use a BigInteger
Edit: Since "print number % 1000000007", you have to declare the following variable in your class
private static final BigInteger MOD = new BigInteger("1000000007");
Then we're going to use the module operator.
public static void nthLongTwoBitSets(long n) {
long r = ((long) Math.sqrt((n << 3) - 1) + 1) >>> 1;
long i = n - ((r * (r - 1)) >>> 1) - 1;
long result = (1L << r) | (1L << i);
result %= 1000000007;
System.out.println(result);
}
public static void nthBigIntegerTwoBitSets(long n) {
int r = ((int) Math.sqrt((n << 3) - 1) + 1) >>> 1;
int i = (int) n - ((r * (r - 1)) >>> 1) - 1;
BigInteger result = BigInteger.ZERO.setBit(r).setBit(i).mod(MOD);
System.out.println(result.toString());
}
Edit2: I cannot access to that link, but if the runtime error is due to a timeout, we have to do some micro-optimization (which are a bad practice in almost every case), so 1) no more BigInteger and 2) only one System.out.println
because it's very expensive. We're going to store the string in a StringBuilder
public class Solution {
private final static long MOD = 1000000007L;
private final static long FIXED = 46480318; // (1L << 42) % mod;
public static void main(String[] args) {
String sep = "\n";
StringBuilder sb = new StringBuilder(90000);
Scanner scan = new Scanner(System.in);
int t = scan.nextInt();
for(int j=0 ; j<t ; j++){
long n = scan.nextInt();
sb.append(nthLongTwoBitSets(n));
sb.append(sep);
}
sb.deleteCharAt(sb.length() - 1);
System.out.println(sb.toString());
}
public static long nthLongTwoBitSets2(final long n) {
long r = ((long) Math.sqrt((n << 3) - 1) + 1) >>> 1;
long i = n - ((r * (r - 1)) >>> 1) - 1;
long rMod = 1;
while (r > 62) {
r -= 42;
rMod *= FIXED;
rMod %= MOD;
}
rMod *= (1L << r);
rMod %= MOD;
long iMod = 1;
while (i > 62) {
i -= 42;
iMod *= FIXED;
iMod %= MOD;
}
iMod *= (1L << i);
iMod %= MOD;
final long result = (rMod + iMod) % MOD;
return result;
}
}