#320ラウンドCodeforces(DIV。1)[バヤンおかげラウンド]
トピックリンク:B.「または」ゲーム
あなたが与えられている\(N \)番号(A_1、A_2、...、A_N \)\。あなたは、最大で実行することができます\(K \)操作。各操作のためには、で数字の1を掛けることができます\(X \) 。私たちは作りたい\を(A_1 | A_2 | ... | A_N \)場合には、できるだけ大きく(| \)\は、ビット単位のORを意味します。
可能な最大値検索(A_N \ | A_2 | | ... A_1)\を最大で実行した後、\(K \)最適に運用。
入力
最初の行は三つの整数含ま\(N \)、\(k個の\)と\(X(1≤N≤200 000、10≤1≤K、≤X≤8 2)\)。
二行目が含まれている\(N \)整数を\(A_1、A_2、...、A_N(0≤≤a_iを10 ^ 9)\) 。
出力
出力ビットごとのOR演算を実行した後、配列の要素の最大値。
例
入力
3 1 2 1 1 1
出力
3
入力
4 2 3 1 2 4 8
出力
79
注意
最初のサンプルでは、一つの操作を行うためのすべての可能な選択肢は、同じ3つの数字を発生します\(1、1、2 \)ので、結果は\(1 | 1 | 2 = 3 \) 。
私たちが掛け場合は、2番目のサンプルについて\(8 \)による\(3 \)我々が得られます2回\(72 \) 。この場合、数字はなるだろう\(1、2、4、72 \)のでOR値となる(\ 79 \)と最大可能結果です。
解決
問題の意味
与えられた\(N- \)数\(A_1 ... A_N \) 、することができる(K \)\オペレーション、それぞれの時間数は任意で乗算することができます\(X \)求めて、A_2 | \(A_1を| ... | A_Nの\)くらいまで。
問題の解決策
プレフィックスと貪欲
以降\(X- \ GE 2 \) 、したがって、とを乗じた数\(X \)不可避のビット数が増加した後。
操作があるかので\(0 | 1 \)の回答が増加した場合、そうしましょう\(K \) A \(X \)同じ行の数を掛けました。
接頭辞と接尾辞と計算して、暴力的な列挙数を乗じ、各\(^ X-のk \)は、最大値を見つけることができます。
コード
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
typedef long long ll;
ll a[maxn], s1[maxn], s2[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
ll n, k, x;
cin >> n >> k >> x;
for(int i = 1; i <= n; ++i) {
cin >> a[i];
s1[i] = s1[i - 1] | a[i];
}
for(int i = n; i >= 1; --i) {
s2[i] = s2[i + 1] | a[i];
}
ll ans = 0;
ll tmp = x;
for(int i = 2; i <= k; ++i) {
tmp *= x;
}
for(int i = 1; i <= n; ++i) {
ans = max(ans, s1[i - 1] | tmp * a[i] | s2[i + 1]);
}
cout << ans << endl;
return 0;
}