码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 460D:Little Victor and Set

时间:2016-08-26 20:04:14      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:

Description

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.

 

 

正解:分类讨论

解题报告:

  今天考试原题,直接上题解:

  分类讨论。
  首先注意到(2x) ⊕ (2x + 1) = 1。一个直接推论就是(2x) ⊕ (2x + 1) ⊕ (2x + 2) ⊕(2x + 3) = 0。而k ≥ 5的时候一定可以选出四个数其异或和为0(例如,如果l是偶数,那么选l, l + 1, l + 2, l + 3,否则选l + 1, l + 2, l + 3, l + 4。这样总是合法的,因为r ≥ l + 4)。
  然后按照k的值分类讨论。
  k = 1。答案就是l。
  k = 2。如果r = l + 1,那么答案是min?(l ⊕ r, l),其中l表示只选一个数,l ⊕ r表示选两个数。否则答案一定为1。当r > l + 1的时候,如果l是偶数,那么答案是l ⊕ (l + 1),否则答案是(l + 1) ⊕ (l + 2)。
  k = 3。答案不会超过1,因为从[l, r]中选两个数一定可以使得答案为1。我们关心的是三个数的异或和为0的情况。这3个数的最高位不可能相同(否则异或起来的最高位为1)。设这三个数为x, y, z(x < y <z),且y = 2 ^k + b, z = 2^ k + c, b < c。那么x ⊕ b ⊕ c = 0。为了让l ≤ x, y, z ≤ r,我们需要使得x尽量大而c尽量小。假设x ≥ 2 ^(k−1) ,那么可以推出z ≥ 2^( k−1) + 2^ k 。我们需要使x尽量大而c尽量小,那么令x = 2 ^(k − 1), z = 2 ^(k−1) + 2^ k ,可以得到y = z − 1。满足要求。那么如果x < 2^( k−1) 呢?我们会发现:此时z没必要≥ 2^ k ,因为取y = 2^( k−1 + b), z = 2 ^(k−1 )+ c依然满足条件。
  所以枚举k并检查x = 2 ^k − 1, z = 2^ k + 2^( k−1) , y = z − 1这三个数是否在[l, r]内,如果在的话,就找到了一组解。
  k = 4。如果r − l ≥ 4,那么答案一定为0。否则,枚举{x|x ∈ Z ∧ l ≤ x ≤ r}的所有子集,求异或和的最小值。

 

  我的代码后面分类讨论部分写丑了。  

 

 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 using namespace std;
14 typedef long long LL;
15 LL l,r,len;
16 int k;
17 LL jilu1,jilu2,jilu3,num;
18 
19 inline int getint()
20 {
21     int w=0,q=0;
22     char c=getchar();
23     while((c<0 || c>9) && c!=-) c=getchar();
24     if (c==-)  q=1, c=getchar();
25     while (c>=0 && c<=9) w=w*10+c-0, c=getchar();
26     return q ? -w : w;
27 }
28 
29 inline LL getlong()
30 {
31     LL w=0,q=0;
32     char c=getchar();
33     while((c<0 || c>9) && c!=-) c=getchar();
34     if (c==-)  q=1, c=getchar();
35     while (c>=0 && c<=9) w=w*10+c-0, c=getchar();
36     return q ? -w : w;
37 }
38 
39 inline LL check(){
40     LL t=0;
41     while( ((1LL<<t)-1LL) < l) t++; 
42     if(( (1LL<<t)+(1LL<<(t-1LL)) )<=r) return t;
43     return -1;
44 }
45 
46 inline void work(){
47     LL now;
48     l=getlong(); r=getlong(); k=getint(); len=r-l+1;
49     if(k==1) printf("%I64d 1\n%I64d",l,l);    
50     else if(k==2) {
51     if(l&1) {
52         if(r-l+1==2){
53         if((l^r)<l)  printf("%I64d 2\n%I64d %I64d",l^r,l,r);
54         else printf("%I64d 1\n%I64d",l,l);
55         }
56         else  printf("1 2\n%I64d %I64d",l+1,l+2);    
57     }        
58     else printf("1 2\n%I64d %I64d",l,l+1);
59     }
60     else if(k==3) {
61     if((now=check())!=-1) {
62         printf("0 3\n"); printf("%I64d ",(1LL<<now)-1LL);
63         printf("%I64d %I64d",(1LL<<now)+(1LL<<(now-1LL))-1LL, (1LL<<now)+(1LL<<(now-1LL) ) );
64     }
65     else { printf("1 2\n"); if(l&1) printf("%I64d %I64d",l+1,l+2); else printf("%I64d %I64d",l,l+1);  }
66     }
67     else{
68     if(l&1) {
69         if(r-l+1>4) printf("0 4\n%I64d %I64d %I64d %I64d",l+1,l+2,l+3,l+4);
70         else{
71         now=l; num=1; for(int i=0;i<4;i++) for(int j=i+1;j<4;j++) if( ((l+i)^(l+j)) < now) now=((l+i)^(l+j)),num=2,jilu1=l+i,jilu2=l+j;
72         if( (l^(l+1)^(l+2) ) < now) now=(l^(l+1)^(l+2) ),num=3,jilu1=l,jilu2=l+1,jilu3=l+2; if( (l^(l+1)^(l+3) ) < now) now=(l^(l+1)^(l+3) ),num=3,jilu1=l,jilu2=l+1,jilu3=l+3;
73         if( (l^(l+2)^(l+3) ) < now) now=(l^(l+2)^(l+3) ),num=3,jilu1=l,jilu2=l+2,jilu3=l+3; if( ((l+1)^(l+2)^(l+3) ) < now) now=((l+1)^(l+2)^(l+3)),num=3,jilu1=l+1,jilu2=l+2,jilu3=l+3;
74         if( (l^(l+1)^(l+2)^(l+3) ) < now) now=(l^(l+1)^(l+2)^(l+3) ),num=4;            
75         printf("%I64d %I64d\n",now,num); if(num==1) printf("%I64d",now); else if(num==2) printf("%I64d %I64d",jilu1,jilu2); else if(num==3) printf("%I64d %I64d %I64d",jilu1,jilu2,jilu3); else printf("%I64d %I64d %I64d %I64d",l,l+1,l+2,l+3);
76         }
77     }
78     else printf("0 4\n%I64d %I64d %I64d %I64d",l,l+1,l+2,l+3);
79     }    
80 }
81 
82 int main()
83 {
84     work();
85     return 0;
86 }

 

codeforces 460D:Little Victor and Set

标签:

原文地址:http://www.cnblogs.com/ljh2000-jump/p/5811378.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!