結果
問題 | No.262 面白くないビットすごろく |
ユーザー | Tatamo |
提出日時 | 2016-02-26 21:42:26 |
言語 | C++11 (gcc 11.4.0) |
結果 |
AC
|
実行時間 | 257 ms / 2,000 ms |
コード長 | 2,469 bytes |
コンパイル時間 | 495 ms |
コンパイル使用メモリ | 56,884 KB |
実行使用メモリ | 339,368 KB |
最終ジャッジ日時 | 2024-09-22 14:02:52 |
合計ジャッジ時間 | 1,614 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 25 ms
44,260 KB |
testcase_01 | AC | 257 ms
339,344 KB |
testcase_02 | AC | 244 ms
339,312 KB |
testcase_03 | AC | 256 ms
339,368 KB |
ソースコード
#include<iostream> inline unsigned long long popcount(unsigned long long x) { return __builtin_popcountll(x); } #define BITS_MAX (40) #define BITS_LOWER (20) using namespace std; typedef unsigned long long ull; struct Point { ull need2overflow; ull next; }; // problems/402 int main() { ull x; cin >> x; const ull n = x; int i = 0; ull tmp = n; while (true) { if (tmp >> 1 == 0) break; tmp = tmp >> 1; i++; } ull nbits = i; ull bits_upper = nbits >= BITS_LOWER ? nbits - BITS_LOWER : 1; bits_upper++; // 行き過ぎるために多少オーバーすることがあるので、一桁多く取る //Point P[BITS_MAX][1 << BITS_LOWER]; Point** P = new Point*[bits_upper]; for (int i = 0; i < bits_upper; i++) { P[i] = new Point[1 << BITS_LOWER]; for (int ii = 0; ii < 1 << BITS_LOWER; ii++) { P[i][ii].need2overflow = 0; } } ull* bits_pc = new ull[1 << BITS_LOWER]; for (int i = 0; i < 1 << BITS_LOWER; i++) { bits_pc[i] = popcount(i); } // 下BITS_LOWERビットについて調べる for (int i = 0; i < bits_upper; i++) { for (long long ii = (1 << BITS_LOWER) - 1; ii >= 0; ii--) { if (i == 0 && ii == 0) continue; ull bit = ii; ull max = (1 << BITS_LOWER); ull c = 0; while (true) { c++; bit += i + bits_pc[bit]; if (bit >= max) { bit -= max; break; } if (P[i][bit].need2overflow > 0) { // DP c += P[i][bit].need2overflow; bit = P[i][bit].next; break; } } P[i][ii].need2overflow = c; P[i][ii].next = bit; //cout << "[" << i << "][" << ii << "]: " << P[i][ii].need2overflow << ", " << P[i][ii].next << endl; } } long long result = -1; ull upper = 0; ull lower = 1; ull count = 1; ull current_upper = upper; ull current_lower = lower; ull current_count = count; ull upc = popcount(upper); while (true) { current_upper = upper; current_lower = lower; current_count = count; upc = popcount(upper); count += P[upc][lower].need2overflow; lower = P[upc][lower].next; upper++; ull pos = (upper << BITS_LOWER) + lower; if (pos >= n) { // 行き過ぎ // 一つ戻す count = current_count; upper = current_upper; lower = current_lower; pos = (upper << BITS_LOWER) + lower; // 普通に計算する while (true) { if (pos == n) { result = count; break; } else if (pos > n) break; pos += popcount(pos); count++; } break; } } cout << result << endl; return 0; }