The Next
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 943 Accepted Submission(s): 389
Problem Description
Let
L denote the number of 1s in integer
D ’s binary representation. Given two integers
S1 and
S2 , we call
D a WYH number if
S1≤L≤S2 .
With a given
D , we would like to find the next WYH number
Y , which is JUST larger than
D . In other words,
Y is the smallest WYH number among the numbers larger than
D . Please write a program to solve this problem.
Input
The first line of input contains a number
T indicating the number of test cases (
T≤300000 ).
Each test case consists of three integers
D ,
S1 , and
S2 , as described above. It is guaranteed that
0≤D<231 and
D is a WYH number.
Output
For each test case, output a single line consisting of “Case #X: Y”.
X is the test case number starting from 1.
Y is the next WYH number.
Sample Input
Sample Output
Case #1: 12
Case #2: 25
Case #3: 17
Source
2015 ACM/ICPC Asia Regional Hefei Online
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
int num[40];
int sum[40];
ll work(){
ll a,l,r;
scanf("%lld%lld%lld",&a,&l,&r);
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum));
int cnt = 0;
while(a){
num[cnt++] = a&1;
a >>= 1;
}
for(int i = 33;i >= 0; i--){
sum[i] = sum[i+1]+num[i];
}
for(int i = 0;i < 34; i++){
if(num[i] == 0){
int t = 1+sum[i];
if(t+i>=l&&t<=r){
int need = max(l-t,0ll);
num[i] = 1;
for(int j = 0;j < i; j++)
num[j] = 0;
for(int j = 0;j < need; j++)
num[j] = 1;
break;
}
}
}
ll ans = 0;
for(int i = 0;i < 34; i++)
if(num[i])
ans += (1ll<<i);
return ans;
}
int main(){
int t,tt=1;
scanf("%d",&t);
while(t--){
ll ans = work();
printf("Case #%d: %I64d\n",tt++,ans);
}
return 0;
}