いろはちゃんコンテスト Day1 L - をあ ぷろぶれむ
問題: L - をあ ぷろぶれむ
- 各 から右側に区間を伸ばしていくと、ビットを新たに立て続けたものが黒板に書かれていくことになる。ここで、新たに立ったビットが0に戻ることはないため、 の立っているビット数を とすると、黒板に書かれる整数の候補は高々 しかない。そのため、黒板に書かれる整数を全てmapに入れても計算量は となる。
- 区間の左から順番に見て、現在見ている値 を含む全区間 をmapに入れながら処理し続けていくことを考える。ここで、mapに入る整数の種類も上記と同様に考えると高々61種類しかないことがわかる。このことから、途中経過をmapに突っ込みながら探索しても間に合う。
map<ll, ll, greater<ll>> mp1; unordered_map<ll, ll> mp2, mp3; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); ll n, k; cin >> n >> k; vector<ll> a(n); rep(i, n) cin >> a[i]; rep(i, n) { mp2[0]++; for(auto& e: mp2) { ll p = e.first|a[i]; mp3[p] += e.second; mp1[p] += e.second; } swap(mp2, mp3); mp3.clear(); } for(auto& e: mp1) { k -= e.second; if (k <= 0) { cout << e.first << endl; return 0; } } }
提出コード (715ms)
- Submission #5220782 - いろはちゃんコンテスト Day1
- 他の 解法に比べると定数倍が重く、 程度だと 解法と同じくらい時間がかかる。
swap(mp2, mp3)
をmp2 = mp3
にすると毎回mapをコピーするので200msほど遅くなる
効率のよい全探索を書くと自然とこんなコードになる気がするが、計算量が になっていることは非自明ではないだろうか。この記事でも最初は と書いていた。