codeforces 460D Little Victor and Set(构造)

D. Little Victor and Set
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Little Victor adores the sets theory. Let us remind you that a set is a group of numbers where all numbers are pairwise distinct. Today Victor wants to find a set of integers S that has the following properties:

  • for all x  the following inequality holds l ≤ x ≤ r;
  • 1 ≤ |S| ≤ k;
  • lets denote the i-th element of the set S as si; value  must be as small as possible.

Help Victor find the described set.

Input

The first line contains three space-separated integers l, r, k (1 ≤ l ≤ r ≤ 1012; 1 ≤ k ≤ min(106, r - l + 1)).

Output

Print the minimum possible value of f(S). Then print the cardinality of set |S|. Then print the elements of the set in any order.

If there are multiple optimal sets, you can print any of them.

Examples
input
8 15 3
output
1
2
10 11
input
8 30 7
output
0
5
14 9 28 11 16
Note

Operation  represents the operation of bitwise exclusive OR. In other words, it is the XOR operation.


题目大意:从[l,r] 的区间中选择不超过k个数,使选择的数的异或和最小。

题解:r-l+1<5:2^10暴力。
k=1:l即为解。
k=2:一定能构造出异或和为1的解,例如2,3。
k>=4:一定能构造出异或和为0的解,当k=4的时候一定可以选择连续的4个数使异或和为0,如2。3,4,5。
k=3:令m表示2^m大于l且最小的值。
设x=2^m-1,y=2^m+2^(m-1),z=2^m+2^(m-1)-1就是一个异或和为0的解,如果此时y>r,则答案至少是1(可以选择连续的两个数)。
  11111
110000
101111  x,y,z满足这种关系。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
#define I I64d
using namespace std;
LL l,r,k,sum,ans;
LL mark[100],pd[100],mi[1000];
LL cnt,cnt1;
void dfs(LL x,LL sum)
{
	if (x==r+1)
	 {
	 	if (!cnt||cnt>k)  return;
	 	if (sum<ans){
	 		ans=sum; cnt1=cnt;
	 		for (LL i=1;i<=cnt;i++)
	 		 mark[i]=pd[i];
	 	}
	 	return;
	 }
	 ++cnt; pd[cnt]=x; dfs(x+1,sum^x);
	 --cnt;  dfs(x+1,sum);
}
int main()
{
	scanf("%I64d%I64d%I64d",&l,&r,&k);
	if (r-l+1<5)
	{
		ans=1e12;
		dfs(l,0);
		printf("%I64d\n%d\n",ans,cnt1);
		for (int i=1;i<=cnt1;i++)
		 printf("%I64d ",mark[i]);
		printf("\n");
		return 0;
	}
	if (k==1) {
		printf("%I64d\n",l);
		printf("1\n%I64d\n",l);
		return 0;
	}
	if (k==2){
		if (l&1) l++;
		printf("1\n2\n");
		printf("%I64d %I64d\n",l,l+1);
		return 0;
	}
	if (k>=4){
		if (l&1) l++;
		printf("0\n4\n");
		printf("%I64d %I64d %I64d %I64d\n",l,l+1,l+2,l+3);
		return 0;
	}
	mi[0]=1; int t=0;
	for(int i=1;;i++)
	{
		if (mi[i-1]>l)  {
			t=i-1;
			break;
		}
		mi[i]=mi[i-1]*2;
	}
	LL x=mi[t]-1; LL y=mi[t]+mi[t-1]; LL z=mi[t]+mi[t-1]-1;
	if (y<=r){
		printf("0\n3\n");
		printf("%I64d %I64d %I64d\n",x,y,z);
		return 0;
	}
	if (l&1) l++;
    printf("1\n2\n");
	printf("%I64d %I64d\n",l,l+1);
	return 0;
} 



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值