请看以下顺序:3、5、6、9、10、12、17、18、20 ...
该系列中的所有数字在其二进制表示形式中均已精确设置了2位。您的任务很简单,您必须找到此序列的第N个数字。
对于每个测试用例,打印序列的第N个数字,并用换行符分隔。由于数量可能非常大,请打印number % 1000000007
。
我无法弄清楚为什么某些测试用例失败,并且我的代码将在指定范围内工作。
这是我的代码段:
public class Solution {
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner scan=new Scanner(System.in);
int t = scan.nextInt();
for(int j=0 ; j<t ; j++){
long n=scan.nextInt();
long r = 0;
long i = 1;
while((r = i*(i+1)/2) < n)
{
i++;
}
long res = (1<<i) + (1 << (i-(r-n)-1));
System.out.println(res);
}
}
}
答案 0 :(得分:1)
这是一个序列,因此您可以查看正确的百科全书OEIS - Sum of two distinct powers of 2,以查找所需的每条信息。
您还将找到算法。这是其中之一的Java翻译。
for (int j = 0; j < t; j++) {
long n = scan.nextInt();
if (n < 1954) {
nthLongTwoBitSets(n);
} else {
nthBigIntegerTwoBitSets(n);
}
}
r
和i
是两个设置位的索引。
如果必须乘或除以2的幂,则可以使用位移运算符来加快运算速度。
一旦long
的数量变大,就必须使用BigInteger
编辑:由于“打印数量%1000000007”,因此您必须在类中声明以下变量
private static final BigInteger MOD = new BigInteger("1000000007");
然后,我们将使用模块运算符。
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 :我无法访问该链接,但是如果运行时错误是由于超时导致的,我们就必须进行一些微优化(在几乎每种情况下都是不正确的做法),因此1)不再使用BigInteger,而2)仅使用一个System.out.println
,因为它非常昂贵。我们将字符串存储在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;
}
}