您的位置:首页 > 其它

集合 题解

2016-07-27 17:44 176 查看




要求输出方案。

好丧啊...

首先我们可以发现两个pattern...

①(2k)^(2k+1)=1

②(2k)^(2k+1)^(2k+3)^(2k+4)=0

接下来对于k>=4的时候,先把l令为一个大一点的偶数,看一下中间有没有四个。

否则就暴力一波找到有没有三个异或和为0,否则就直接输1。那么我们就枚举这个pattern就可以了。

k=1时显然答案就是l。

k=2时还是要把l变成大一点的偶数,然后如果此时l!=r,那么就直接用第一个pattern输1即可。否则现在就两个数l、r,l为奇数,那么就l^r和l二选一即可。

对于k=3的时候,显然答案也<=1,那么我们能不能构出一个答案为0呢?

考虑这个pattern:

110000000
101111111
011111111


可以发现这个玩意儿是最优的(因为你改第二个不会影响,改第一或第三个只会使区间变大)

如果不能用这个pattern,那就套用k=2的做法就行。

码风略鬼畜...

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
typedef long long ll;
ll l,r,k,t;
ll gll_()
{
ll ans;
scanf("%I64d",&ans);
return ans;
}
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define gll gll_()
int main()
{
FO(set)
t=gll;
while(t--)
{
l=gll, r=gll, k=gll;
k=min(k,r-l+1);
if(k==1)
{
cout<<l<<"\n1\n"<<l<<"\n";
continue;
}
if(k==2)
{
bool s=l&1; l+=s;
if(r-l+1>=2) cout<<1<<"\n2\n"<<l<<" "<<l+1<<"\n";
else
{
l-=s;
if((l^r)>l) cout<<l<<"\n1\n"<<l<<"\n";
else cout<<(l^r)<<"\n2\n"<<l<<" "<<r<<"\n";
}
continue;
}
if(k>=4)
{
bool s=l&1; l+=s;
if(r-l+1>=4) cout<<0<<"\n4\n"<<l<<" "<<l+1<<" "<<l+2<<" "<<l+3<<"\n";
else
{
l-=s;
for(ll a=l;a<=r;a++)
{
for(ll b=l+1;b<=r;b++)
{
for(ll c=b+1;c<=r;c++)
{
if((a^b^c)==0)
{
cout<<"0\n3\n"<<a<<" "<<b<<" "<<c<<"\n";
goto gg;
}
}
}
}
cout<<1<<"\n2\n"<<l+1<<" "<<l+2<<"\n";
gg:;
}
continue;
}
bool ok=0;
for(ll x=1;x<=r;x<<=1)
{
ll a=x+x*2,b=a-1,c=a^b;
if(a<=r&&b<=r&&c<=r&&a>=l&&b>=l&&c>=l);else continue;
cout<<0<<"\n3\n"<<a<<" "<<b<<" "<<c<<"\n";
ok=1; break;
}
if(ok) continue;
bool s=l&1; l+=s;
if(r-l+1>=2) cout<<1<<"\n2\n"<<l<<" "<<l+1<<"\n";
else
{
l-=s;
if((l^r)>l) cout<<l<<"\n1\n"<<l<<"\n";
else cout<<(l^r)<<"\n2\n"<<l<<" "<<r<<"\n";
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: