ディレクトリ
@説明@
数Nを与え、操作を任意の異なる数又は2で置換される毎に2つの数値を選択することができます。
任意の必要な操作の後、すべての数の最終的な最大値。
クラス:
XorAndSum
方法:
maxSum
パラメータ:
長い[]
戻り値:
ロング
サンプル:
{1,2,3}
戻り値:8
制約
すべての重みの数<= 10 ^ 15を確実にするN <= 50の数の数。
@溶液@
最大、XORこれらのキーワードは、リニアグループを考えることは難しいことではありません。
同時に、それは非常にガウス消去、別の方程式方程式の排他的論理和演算などの操作対象与え、見つけることができます。
これは、我々が線形グループを作成する複数の決定です。
我々は、0と同様ガウスの消去、すべての線形除去の外側グループの数を練習することができ、その後、最大値は、排他的又は直鎖状の基にXORすることによって得ることができます。
最大値を取得する方法を線形グループの数を考えてみましょう。
我々は、排他的OR 0の全ての列に、簡単にするために各行(もしあれば)の主要素を類推イル線形ガウスの消去法を継続します。
その後?直鎖状または^ 2種排他数kとすることができるサイズkの群において見出さ、我々はk個の主成分の合計を有することができ、主要素は、各選択されたプログラムのために決定される選択されていない数2 ^ Kです。そして、二人は一から一です。
その配置の主要な要素のすべてを選択:私たちは、各グループの最終的な数は最大線形であることを願っています。しかし、我々は彼らの列は1です各行に二つ以上の主成分は、紛争につながる反対の証拠がある場合、定義リニアグループは単純なことができることを見ることができます。
これは、主要素が配置されているため、0がなければならない、唯一の例外であることを意味します。もちろん、我々は最大の主が最適である。この例外を配置します。
したがって最大線群とで構成することができる:すべての主要な要素(すなわち、最大値は排他的論理和することができる)、常に不足している他のPCAの数の数を選択します。
私は上記に書いたかわかりません。あなたも見ることができyhn先輩のブログ。
@acceptedコード@
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
class XorAndSum{
public:
ll b[60 + 5];
void insert(ll x) {
for(int i=60;i>=0;i--)
if( x & (1LL<<i) ) {
if( b[i] == 0 )
b[i] = x;
x ^= b[i];
}
}
ll get_max() {
for(int i=60;i>=0;i--)
for(int j=i-1;j>=0;j--)
if( b[i] & (1LL<<j) )
b[i] ^= b[j];
ll ret = 0;
for(int i=60;i>=0;i--)
ret ^= b[i];
return ret;
}
ll maxSum(vector<ll>v) {
for(int i=0;i<v.size();i++)
insert(v[i]);
ll x = get_max(), ans = v.size()*x;
bool fir = true;
for(int i=60;i>=0;i--)
if( b[i] ) {
if( fir )
fir = false;
else
ans = ans - x + (x^b[i]);
}
return ans;
}
};
@詳細@
先生:このエントリは、タイトルの線形ベースではないでしょうか?あなたの試験時間がさえこれを書いている余裕はありませんか?
I:......
全世界を行うにはどのように私をからかっています。。。