Description
一个集合包含一组相互不同的数字。现在我们要去寻找一个集合,他要满足如下性质:
对于所有 x(x∈S) ,要满足l ≤ x ≤ r;
1 ≤ |S| ≤ k;
设S中第i个元素是 si ;那么 f(S)=s1 ⨁ s2 ⨁ … ⨁ s|S| 的值要尽可能小。
Sample Input
8 15 3
Sample Output
1
这道题k=1,2,4的情况比较显然,k=3,你设r的从左往右第二个进制为z,t=(1<<(z+1))-1,若l<=t,则可用三个数合成:r,t,r^t
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
LL _min(LL x, LL y) {return x < y ? x : y;}
LL bin[41];
int main() {
LL l, r; int k;
scanf("%lld%lld%d", &l, &r, &k);
if(k == 1) printf("%lld\n", l);
else if(k == 2) {
if(r - l >= 2) printf("1\n");
else if(r - l == 0) printf("%lld\n", l);
else {
LL u = l ^ r;
if(u < l) printf("%lld\n", u);
else printf("%lld\n", l);
}
} else if(k >= 4){
if(r - l == 0) printf("%lld\n", l);
else if(r - l == 1) {
LL u = l ^ r;
if(u < l) printf("%lld\n", u);
else printf("%lld\n", l);
} else if(r - l == 2){
LL hh = _min(_min(l, l + 1), l + 2);
hh = _min(hh, (l + 1) ^ l);
hh = _min(hh, (l + 1) ^ r);
hh = _min(hh, l ^ r);
hh = _min(hh, l ^ (l + 1) ^ r);
printf("%lld\n", hh);
} else if(r - l == 3) {
if(l % 2 == 0) printf("0\n");
else {
if(r <= 6) printf("0\n");
else printf("1\n");
}
} else printf("0\n");
} else {
if(l == r) printf("%lld\n", l);
else if(r - l == 1) {
LL u = l ^ r;
if(u < l) printf("%lld\n", u);
else printf("%lld\n", l);
}
else {
int u = 0, p, o;
bin[0] = 1; for(int i = 1; i <= 40; i++) bin[i] = bin[i - 1] * 2LL;
for(int i = 40; i >= 0; i--) if(bin[i] <= r){
if(u == 1) o = i;
r -= bin[i], u++;
p = i;
} if(u == 1) {
if(p == 2) {
if(l == 2) printf("1\n");
else printf("0\n");
} p -= 1;
if(bin[p] - 1 >= l) printf("0\n");
else printf("1\n");
} else {
if(bin[o + 1] - 1 >= l) printf("0\n");
else printf("1\n");
}
}
}
return 0;
}