DreamGrid has a nonnegative integer should be as small as possible).
Input
There are multiple test cases. The first line of input contains an integer , indicating the number of test cases. For each test case:
The first line contains two integers ).
It is guaranteed that the sum of the length of .
<h4< dd="">Output
For each test case, output an integer denoting the minimum value of their bitwise or.
<h4< dd="">Sample Input
5 3 1 3 2 3 3 10000 5 1244 10
<h4< dd="">Sample Output
3 3 1 2000 125
题解:题意很简单,就是让你把n分成m份,然后让你求这m份按位或的最小值;(注意数据范围,大数模板考虑下Orz)
考虑一个k满足m*2^k <= n < m*2^(k+1)如果使得结果最小,则对于分开后,每个数的最高位(二进制)位置越小,找到一个k后,我们让这m个数字第k位都为一。
然后剩下n-m*2^k(相当于新的n),递归求解即可;
参考代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 // base and base_digits must be consistent 4 constexpr int base = 1000000000; 5 constexpr int base_digits = 9; 6 struct bigint 7 { 8 vector<int> z; 9 int sign; 10 bigint() : sign(1) {} 11 bigint(long long v) 12 { 13 *this = v; 14 } 15 bigint& operator=(long long v) 16 { 17 sign = v < 0 ? -1 : 1; 18 v *= sign; 19 z.clear(); 20 for(; v > 0; v = v / base) z.push_back((int)(v % base)); 21 return *this; 22 } 23 24 bigint(const string& s) 25 { 26 read(s); 27 } 28 29 bigint& operator+=(const bigint& other) 30 { 31 if (sign == other.sign) 32 { 33 for (int i = 0, carry = 0; i < other.z.size() || carry; ++i) 34 { 35 if(i == z.size()) z.push_back(0); 36 z[i] += carry + (i < other.z.size() ? other.z[i] : 0); 37 carry = z[i] >= base; 38 if(carry) z[i] -= base; 39 } 40 } 41 else if (other != 0 /* prevent infinite loop */) 42 { 43 *this -= -other; 44 } 45 return *this; 46 } 47 48 friend bigint operator+(bigint a, const bigint& b) 49 { 50 return a += b; 51 } 52 53 bigint& operator-=(const bigint& other) 54 { 55 if (sign == other.sign) 56 { 57 if (sign == 1 && *this >= other || sign == -1 && *this <= other) 58 { 59 for (int i = 0, carry = 0; i < other.z.size() || carry; ++i) 60 { 61 z[i] -= carry + (i < other.z.size() ? other.z[i] : 0); 62 carry = z[i] < 0; 63 if(carry) z[i] += base; 64 } 65 trim(); 66 } 67 else 68 { 69 *this = other - *this; 70 this->sign = -this->sign; 71 } 72 } 73 else *this += -other; 74 return *this; 75 } 76 77 friend bigint operator - (bigint a, const bigint& b) 78 { 79 return a -= b; 80 } 81 82 bigint& operator*=(int v) 83 { 84 if(v < 0) sign = -sign, v = -v; 85 for(int i = 0, carry = 0; i < z.size() || carry; ++i) 86 { 87 if(i == z.size()) z.push_back(0); 88 long long cur = (long long)z[i] * v + carry; 89 carry = (int)(cur / base); 90 z[i] = (int)(cur % base); 91 } 92 trim(); 93 return *this; 94 } 95 96 bigint operator*(int v) const 97 { 98 return bigint(*this) *= v; 99 } 100 101 friend pair<bigint, bigint> divmod(const bigint& a1, const bigint& b1) 102 { 103 int norm = base / (b1.z.back() + 1); 104 bigint a = a1.abs() * norm; 105 bigint b = b1.abs() * norm; 106 bigint q, r; 107 q.z.resize(a.z.size()); 108 109 for (int i = (int)a.z.size() - 1; i >= 0; i--) 110 { 111 r *= base; 112 r += a.z[i]; 113 int s1 = b.z.size() < r.z.size() ? r.z[b.z.size()] : 0; 114 int s2 = b.z.size() - 1 < r.z.size() ? r.z[b.z.size() - 1] : 0; 115 int d = (int)(((long long)s1 * base + s2) / b.z.back()); 116 r -= b * d; 117 while(r < 0) r += b, --d; 118 q.z[i] = d; 119 } 120 121 q.sign = a1.sign * b1.sign; 122 r.sign = a1.sign; 123 q.trim(); 124 r.trim(); 125 return {q, r / norm}; 126 } 127 128 friend bigint sqrt(const bigint& a1) 129 { 130 bigint a = a1; 131 while(a.z.empty() || a.z.size() % 2 == 1) a.z.push_back(0); 132 133 int n = a.z.size(); 134 int firstDigit = (int)::sqrt((double)a.z[n - 1] * base + a.z[n - 2]); 135 int norm = base / (firstDigit + 1); 136 a *= norm; 137 a *= norm; 138 while(a.z.empty() || a.z.size() % 2 == 1) a.z.push_back(0); 139 140 bigint r = (long long)a.z[n - 1] * base + a.z[n - 2]; 141 firstDigit = (int)::sqrt((double)a.z[n - 1] * base + a.z[n - 2]); 142 int q = firstDigit; 143 bigint res; 144 for (int j = n / 2 - 1; j >= 0; j--) 145 { 146 for(;; --q) 147 { 148 bigint r1 = (r - (res * 2 * base + q) * q) * base * base + (j > 0 ? (long long)a.z[2 * j - 1] * base + a.z[2 * j - 2] : 0); 149 if(r1 >= 0) 150 { 151 r = r1; 152 break; 153 } 154 } 155 res *= base; 156 res += q; 157 if(j > 0) 158 { 159 int d1 = res.z.size() + 2 < r.z.size() ? r.z[res.z.size() + 2] : 0; 160 int d2 = res.z.size() + 1 < r.z.size() ? r.z[res.z.size() + 1] : 0; 161 int d3 = res.z.size() < r.z.size() ? r.z[res.z.size()] : 0; 162 q = (int)(((long long)d1 * base * base + (long long)d2 * base + d3) / (firstDigit * 2)); 163 } 164 } 165 166 res.trim(); 167 return res / norm; 168 } 169 170 bigint operator/(const bigint& v) const 171 { 172 return divmod(*this, v).first; 173 } 174 175 bigint operator%(const bigint& v) const 176 { 177 return divmod(*this, v).second; 178 } 179 180 bigint& operator/=(int v) 181 { 182 if(v < 0) sign = -sign, v = -v; 183 for (int i = (int)z.size() - 1, rem = 0; i >= 0; --i) 184 { 185 long long cur = z[i] + rem * (long long)base; 186 z[i] = (int)(cur / v); 187 rem = (int)(cur % v); 188 } 189 trim(); 190 return *this; 191 } 192 193 bigint operator/(int v) const 194 { 195 return bigint(*this) /= v; 196 } 197 198 int operator%(int v) const 199 { 200 if(v < 0) v = -v; 201 int m = 0; 202 for(int i = (int)z.size() - 1; i >= 0; --i) m = (int)((z[i] + m * (long long)base) % v); 203 return m * sign; 204 } 205 206 bigint& operator*=(const bigint& v) 207 { 208 *this = *this * v; 209 return *this; 210 } 211 212 bigint& operator/=(const bigint& v) 213 { 214 *this = *this / v; 215 return *this; 216 } 217 218 bool operator<(const bigint& v) const 219 { 220 if(sign != v.sign) return sign < v.sign; 221 if(z.size() != v.z.size()) return z.size() * sign < v.z.size() * v.sign; 222 for(int i = (int)z.size() - 1; i >= 0; i--) 223 if(z[i] != v.z[i]) return z[i] * sign < v.z[i] * sign; 224 return false; 225 } 226 227 bool operator>(const bigint& v) const 228 { 229 return v < *this; 230 } 231 bool operator<=(const bigint& v) const 232 { 233 return !(v < *this); 234 } 235 bool operator>=(const bigint& v) const 236 { 237 return !(*this < v); 238 } 239 bool operator==(const bigint& v) const 240 { 241 return !(*this < v) && !(v < *this); 242 } 243 bool operator!=(const bigint& v) const 244 { 245 return *this < v || v < *this; 246 } 247 248 void trim() 249 { 250 while(!z.empty() && z.back() == 0) z.pop_back(); 251 if(z.empty()) sign = 1; 252 } 253 254 bool isZero() const 255 { 256 return z.empty(); 257 } 258 259 friend bigint operator-(bigint v) 260 { 261 if(!v.z.empty()) v.sign = -v.sign; 262 return v; 263 } 264 265 bigint abs() const 266 { 267 return sign == 1 ? *this : -*this; 268 } 269 270 long long longValue() const 271 { 272 long long res = 0; 273 for(int i = (int)z.size() - 1; i >= 0; i--) res = res * base + z[i]; 274 return res * sign; 275 } 276 277 friend bigint gcd(const bigint& a, const bigint& b) 278 { 279 return b.isZero() ? a : gcd(b, a % b); 280 } 281 282 friend bigint lcm(const bigint& a, const bigint& b) 283 { 284 return a / gcd(a, b) * b; 285 } 286 287 void read(const string& s) 288 { 289 sign = 1; 290 z.clear(); 291 int pos = 0; 292 while(pos < s.size() && (s[pos] == '-' || s[pos] == '+')) 293 { 294 if(s[pos] == '-') sign = -sign; 295 ++pos; 296 } 297 for(int i = (int)s.size() - 1; i >= pos; i -= base_digits) 298 { 299 int x = 0; 300 for(int j = max(pos, i - base_digits + 1); j <= i; j++) x = x * 10 + s[j] - '0'; 301 z.push_back(x); 302 } 303 trim(); 304 } 305 306 friend istream& operator>>(istream& stream, bigint& v) 307 { 308 string s; 309 stream >> s; 310 v.read(s); 311 return stream; 312 } 313 314 friend ostream& operator<<(ostream& stream, const bigint& v) 315 { 316 if(v.sign == -1) stream << '-'; 317 stream << (v.z.empty() ? 0 : v.z.back()); 318 for(int i = (int)v.z.size() - 2; i >= 0; --i) 319 stream << setw(base_digits) << setfill('0') << v.z[i]; 320 return stream; 321 } 322 323 static vector<int> convert_base(const vector<int>& a, int old_digits, int new_digits) 324 { 325 vector<long long> p(max(old_digits, new_digits) + 1); 326 p[0] = 1; 327 for(int i = 1; i < p.size(); i++) p[i] = p[i - 1] * 10; 328 vector<int> res; 329 long long cur = 0; 330 int cur_digits = 0; 331 for(int v : a) 332 { 333 cur += v * p[cur_digits]; 334 cur_digits += old_digits; 335 while (cur_digits >= new_digits) 336 { 337 res.push_back(int(cur % p[new_digits])); 338 cur /= p[new_digits]; 339 cur_digits -= new_digits; 340 } 341 } 342 res.push_back((int)cur); 343 while(!res.empty() && res.back() == 0) 344 res.pop_back(); 345 return res; 346 } 347 348 typedef vector<long long> vll; 349 static vll karatsubaMultiply(const vll& a, const vll& b) 350 { 351 int n = a.size(); 352 vll res(n + n); 353 if(n <= 32) 354 { 355 for (int i = 0; i < n; i++) 356 for (int j = 0; j < n; j++) 357 res[i + j] += a[i] * b[j]; 358 return res; 359 } 360 361 int k = n >> 1; 362 vll a1(a.begin(), a.begin() + k); 363 vll a2(a.begin() + k, a.end()); 364 vll b1(b.begin(), b.begin() + k); 365 vll b2(b.begin() + k, b.end()); 366 vll a1b1 = karatsubaMultiply(a1, b1); 367 vll a2b2 = karatsubaMultiply(a2, b2); 368 for(int i = 0; i < k; i++) a2[i] += a1[i]; 369 for(int i = 0; i < k; i++) b2[i] += b1[i]; 370 371 vll r = karatsubaMultiply(a2, b2); 372 for(int i = 0; i < a1b1.size(); i++) r[i] -= a1b1[i]; 373 for(int i = 0; i < a2b2.size(); i++) r[i] -= a2b2[i]; 374 for(int i = 0; i < r.size(); i++) res[i + k] += r[i]; 375 for(int i = 0; i < a1b1.size(); i++) res[i] += a1b1[i]; 376 for(int i = 0; i < a2b2.size(); i++) res[i + n] += a2b2[i]; 377 return res; 378 } 379 380 bigint operator*(const bigint& v) const 381 { 382 vector<int> a6 = convert_base(this->z, base_digits, 6); 383 vector<int> b6 = convert_base(v.z, base_digits, 6); 384 vll a(a6.begin(), a6.end()); 385 vll b(b6.begin(), b6.end()); 386 while(a.size() < b.size()) a.push_back(0); 387 while(b.size() < a.size()) b.push_back(0); 388 while(a.size() & (a.size() - 1)) a.push_back(0), b.push_back(0); 389 vll c = karatsubaMultiply(a, b); 390 bigint res; 391 res.sign = sign * v.sign; 392 for (int i = 0, carry = 0; i < c.size(); i++) 393 { 394 long long cur = c[i] + carry; 395 res.z.push_back((int)(cur % 1000000)); 396 carry = (int)(cur / 1000000); 397 } 398 res.z = convert_base(res.z, 6, base_digits); 399 res.trim(); 400 return res; 401 } 402 }; 403 /*********************************************** 404 上面为大数模板 核心代码 405 ************************************************/ 406 int main() 407 { 408 ios::sync_with_stdio(0); 409 cin.tie(0); 410 bigint n, m; 411 int T; 412 cin >> T; 413 while(T--) 414 { 415 cin >> n >> m; 416 bigint ans = 0; 417 bigint now = 1; 418 while(now<= n) 419 { 420 now = now * 2; 421 } 422 while(n != 0) 423 { 424 while(now != 1 && now * m > n) 425 { 426 now = now / 2; 427 } 428 if((now * 2 - 1) * m < n) 429 now = now * 2; 430 bigint num = n / now; 431 if(num > m) 432 num = m; 433 n = n - num * now; 434 ans = ans + now; 435 } 436 cout << ans << endl; 437 } 438 return 0; 439 } 440