Codeforces Round #262 (Div. 2) 1004
D. Little Victor and Set
time limit per test
1 secondmemory limit per test
256 megabytesinput
standard inputoutput
standard outputLittle 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.
Sample test(s)
input
8 15 3output
12
10 11
input
8 30 7output
05
14 9 28 11 16
Note
Operation
【分析】很显然的结论,K^(K+1)=1,其中K是偶数。当K>3时,我们可以选连续的4个自然数使异或和为0。(当然注意要特判R-L+1的大小)。当K=1时,就是L。当K=2时,显然只能构造异或为1的情况。
所有的推论都指向一个问题:当K=3的一般情况怎么做?
【题解】对于那个情况,我一直觉得能贪心构造,但是怎么也想不出简单易行且效率高的算法。
其实很简单。我们设L<=X<Y<Z<=R,然后来贪心构造他们。
在二进制中,异或和为0的情况是1,1,0或0,0,0。显然Z的第一位是1,然后X和Y是0。
因为是贪心,我们要尽量使Y靠近Z(因为如果Z符合范围,Y显然越大越好)。
那么第二位我们就让Y靠近Z。我们把Z那位设成0,X和Y都设成1,即如下形式:
110000000
101111111
011111111
wa了很多次,
1.没有用long long
2.只有l^(l+1) l为偶数时,才能异或值为1
3.当k>=4但是不存在4个数异或为0的时候,没考虑3个也可能为0
4.1<<35超过int 得写成(long long)1<<35
5.当2个异或不是1时,应该判断他的值和l的大小
1 #include <cstring> 2 3 #include <iostream> 4 5 #include <algorithm> 6 7 #include <cstdio> 8 9 #include <cmath> 10 11 #include <map> 12 13 #include <cstdlib> 14 15 #define M(a,b) memset(a,b,sizeof(a)) 16 17 #define INF 0x3f3f3f3f 18 19 using namespace std; 20 21 22 23 long long l,r,k; 24 25 26 27 int main() 28 29 { 30 31 scanf("%I64d%I64d%I64d",&l,&r,&k); 32 33 if(k==1) printf("%I64d\n1\n%I64d\n",l,l); 34 35 else if(k==2) 36 37 { 38 39 if(l%2==0) 40 41 printf("1\n2\n%I64d %I64d\n",l,l+1); 42 43 else if(l+2<=r) 44 45 printf("1\n2\n%I64d %I64d\n",l+1,l+2); 46 47 else if(((l)^(l+1))<l) { 48 49 //cout<<(((l)^(l+1))-l)<<endl; 50 51 printf("%I64d\n2\n%I64d %I64d\n",(l)^(l+1),l,l+1); 52 53 } 54 55 else printf("%I64d\n1\n%I64d\n",l,l); 56 57 } 58 59 else if(k>=4) 60 61 { 62 63 if(l%2==0) 64 65 printf("0\n4\n%I64d %I64d %I64d %I64d\n",l,l+1,l+2,l+3); 66 67 else if(l+3<r) 68 69 printf("0\n4\n%I64d %I64d %I64d %I64d\n",l+1,l+2,l+3,l+4); 70 71 else if(((l)^(l+1)^(l+2)^(l+3))==0)printf("0\n4\n%I64d %I64d %I64d %I64d\n",l,l+1,l+2,l+3); 72 73 else 74 75 { 76 77 int count1 = 0; 78 79 long long tem1 = r; 80 81 while(tem1>0) 82 83 { 84 85 tem1 = tem1>>1; 86 87 count1++; 88 89 } 90 91 //cout<<count1<<endl; 92 93 int cnt = 0; 94 95 long long ans1 = 0; 96 97 long long ans2 = 0; 98 99 for(int i = count1-1;i>=0;i--) 100 101 { 102 103 if(((r>>i)&1)==1) 104 105 { 106 107 if(cnt == 0) 108 109 { 110 111 ans1 = ans1|((long long)1<<i); 112 113 cnt++; 114 115 } 116 117 else if(cnt >= 1) 118 119 { 120 121 ans2 = ans2|((long long)1<<i); 122 123 cnt++; 124 125 } 126 127 } 128 129 else 130 131 { 132 133 if(cnt>1) 134 135 { 136 137 ans1 = ans1|((long long)1<<i); 138 139 ans2 = ans2|((long long)1<<i); 140 141 } 142 143 } 144 145 } 146 147 if(ans2<l) 148 149 { 150 151 if(l%2==0) 152 153 printf("1\n2\n%I64d %I64d\n",l,l+1); 154 155 else printf("1\n2\n%I64d %I64d\n",l+1,l+2); 156 157 } 158 159 else printf("0\n3\n%I64d %I64d %I64d\n",ans1,ans2,r); 160 161 } 162 163 } 164 165 else 166 167 { 168 169 int count1 = 0; 170 171 long long tem1 = r; 172 173 while(tem1>0) 174 175 { 176 177 tem1 = tem1>>1; 178 179 count1++; 180 181 } 182 183 //cout<<count1<<endl; 184 185 int cnt = 0; 186 187 long long ans1 = 0; 188 189 long long ans2 = 0; 190 191 for(int i = count1-1;i>=0;i--) 192 193 { 194 195 if(((r>>i)&1)==1) 196 197 { 198 199 if(cnt == 0) 200 201 { 202 203 ans1 = ans1|((long long)1<<i); 204 205 cnt++; 206 207 } 208 209 else if(cnt >= 1) 210 211 { 212 213 ans2 = ans2|((long long)1<<i); 214 215 cnt++; 216 217 } 218 219 } 220 221 else 222 223 { 224 225 if(cnt>1) 226 227 { 228 229 ans1 = ans1|((long long)1<<i); 230 231 ans2 = ans2|((long long)1<<i); 232 233 } 234 235 } 236 237 //cout<<ans2<<' '<<ans1<<endl; 238 239 } 240 241 //cout<<ans2<<' '<<ans1<<endl; 242 243 if(ans2<l) 244 245 { 246 247 if(l%2==0) 248 249 printf("1\n2\n%I64d %I64d\n",l,l+1); 250 251 else printf("1\n2\n%I64d %I64d\n",l+1,l+2); 252 253 } 254 255 else printf("0\n3\n%I64d %I64d %I64d\n",ans1,ans2,r); 256 257 } 258 259 return 0; 260 261 }