Numbers
Time Limit: 2 Seconds Memory Limit: 65536 KB
DreamGrid has a nonnegative integer . He would like to divide into nonnegative integers and minimizes their bitwise or (i.e. and should be as small as possible).
Input
There are multiple test cases. The first line of input contains an integer , indicating the number of test cases. For each test case:
The first line contains two integers and ().
It is guaranteed that the sum of the length of does not exceed .
Output
For each test case, output an integer denoting the minimum value of their bitwise or.
Sample Input
5
3 1
3 2
3 3
10000 5
1244 10
Sample Output
3
3
1
2000
125
Author: LIN, Xi
Source: The 2017 China Collegiate Programming Contest, Qinhuangdao Site
题意:n由m个数组成,n=a1+a2+...+am。求a1 or a2 or ...or am的最小值。
思路:将n看作由m个二进制数构成的数,对于这m个数,我们希望它们的二进制为1的位置尽可能的低,因为题目要求或运算的结果尽可能的小。
我们从n的二进制最高位开始遍历,这m个数只有当k位置必须放置1时,我们才在第k位放置1,其他情况放置0。必须放置1的情况为:(2^k-1)*m>=n 并且(2*(k-1)-1)*m<n,表示如果我在k位置不放置1,后面的位置全部放置1也小于n,所以我们至少需要在k位置放置1个1,既然这个位置确定要放置1了,我们就尽可能的多放置1,使得后面放置1的位置尽可能的低,ans=ans+2^k。
因为数据的范围很大,需要用到java的BigInteger类
AC代码:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
BigInteger n,m,ans,tmp,num,cnt;
Scanner sc = new Scanner(System.in);
int T=sc.nextInt();
while(T-->0) {
n = sc.nextBigInteger();
m = sc.nextBigInteger();
ans = BigInteger.ZERO;
tmp = n;
int len=0;
while(tmp.compareTo(BigInteger.ZERO)>0) {
tmp=tmp.divide(BigInteger.valueOf(2));
len++;
}
//组成n的二进制最高位为2^(len-1)
for(int i=len-1;i>=0;i--) {
//num1=(2^k-1)*m
num = BigInteger.valueOf(2).pow(i).subtract(BigInteger.ONE).multiply(m);
if(num.compareTo(n)<0) {
cnt = n.divide(BigInteger.valueOf(2).pow(i));
if(cnt.compareTo(m)>0)
cnt=m;
n=n.subtract(BigInteger.valueOf(2).pow(i).multiply(cnt));
ans=ans.add(BigInteger.valueOf(2).pow(i));
}
}
System.out.println(ans);
}
}
}