D. Little Victor and Set
题意:你有一个整型的集合,里面的元素不小于l,不大于r,至少有一个元素,至多有k个元素。你需要让这个集合所有元素进行异或运算后的值最小。输出所有元素异或后的值和任一个满足条件的集合。
思路:先分析一下,如果k=1,那么集合肯定是l~r中最小的元素,也就是l。如果k=2,很容易想到一个偶数2n和2n+1异或的结果一定是1,当然,k为2的时候会受到lr的制约,也就是未必能异或成1。然后考虑k>=4的情况,如果能弄出两个1,那么两个1异或以后就是0了,不可能有比0更优的解,一样能否异或成0还是要受到lr的约束。
最困难的情况是k=3,有的情况下三个数能异或为0的,怎样的三个数异或能得到0呢?不妨考虑二进制表示。比如一个数111111,有没有数异或得到它呢,有,如1 100000和1 011111,当然111 111 000和111 000 111也是可以的,满足条件的最小值是前者。我们就需要测试有没有这样的三个数在lr范围内。
详细分类情况见代码。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <memory.h>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <ctype.h>
#include <sstream>
#define INF 1000000
#define ll long long
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define MAXN 100010
using namespace std;
int main() {
ll l,r,k;
while(cin>>l>>r>>k){
if(l==r){
cout<<l<<endl;
cout<<1<<endl;
cout<<l<<endl;
}else{
if(k==1){
cout<<l<<endl;
cout<<1<<endl;
cout<<l<<endl;
continue;
}else if(l+1==r){
if((l^r)<l){
cout<<(l^r)<<endl;
cout<<2<<endl;
cout<<l<<" "<<r<<endl;
}else{
cout<<l<<endl;
cout<<1<<endl;
cout<<l<<endl;
}
}else{
if(k==3||(k>3&&l+3==r)){
bool find=false;
ll t=1;
while(t<=l)t<<=1;
t+=t/2;
if(t<=r){
cout<<0<<endl;
cout<<3<<endl;
cout<<(t^(t-1))<<" "<<t<<" "<<t-1<<endl;
find=true;
}
if(find)continue;
}
if(k<4||(l+3==r&&(l&1))){
if(l&1)l++;
cout<<1<<endl;
cout<<2<<endl;
cout<<l<<" "<<l+1<<endl;
}else{
if(l&1)l++;
cout<<0<<endl;
cout<<4<<endl;
cout<<l<<" "<<l+1<<" "<<l+2<<" "<<l+3<<endl;
}
}
}
}
return 0;
}