Entries

スポンサーサイト (この記事を編集する[管理者用])

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://rsujskf.blog32.fc2.com/tb.php/2300-b93e782f
この記事にトラックバックする(FC2ブログユーザー)

SRM557 DIV1 HARD - XorAndSum (この記事を編集する[管理者用])

Source

TopCoder SRM557 DIV1 HARD (1000pt)
Problem Statement

問題概要

n要素の非負整数からなる数列が与えられる.nは50以下で,各要素は10^15以下.
好きなだけ以下の操作を行う.
 数列の要素A[i]とA[j]を取ってきて,A[i]をA[i] XOR A[j]に変える.(A[j]はそのまま,iとjは異なってなければならない)
最終的に得られる数列の各要素の和の最大値求める問題.

解法

Ad-hocかつgreedyにやる.色々やりかたはあるみたいだけど,以下は自分の解法.
まず最上位ビットが1な要素を1つだけにする.
その要素を取り除いた時に,最上位ビットが1なのを1つだけにする.
と繰り返していき,基底を作る.幾つかの要素は0になるが,それは最後に最大値とXOR取れば良いので除外して考える.
最上位ビットを保ったまま,それぞれの数字を最小化する.
それは,自分の最上位ビットより下位ビットしかないものとXORを取って減るならgreedyにXORを取るというのを繰り返せば良い.
次に最も大きい要素だけ最大値にする.それも,greedyにXOR取る.
後は,最大値以外の全ての要素は最大値とXORを取って終わり.
これで和が最大になる証明は難しくないと思う.

C++によるスパゲッティなソースコード
// #includeとusing namespace std;は略

#define REP(i,a,b) for(i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)

#define ll long long

class XorAndSum {
public:
ll maxSum(vector<ll> in) {
  int i,j,k,n;
  int fixed;
  ll zeros = 0, las;
  ll res = 0;

  sort(in.begin(), in.end());

  while(in.size() && in[0]==0) zeros++, in.erase(in.begin());
  if(!in.size()) return 0;

  fixed = 0;
  while(fixed < in.size()){
    las = in[in.size()-1-fixed];
    rep(i,(int)in.size() - fixed - 1){
      if( (in[i]^las) < in[i] ) in[i] ^= las;
    }
    sort(in.begin(), in.end());
    while(in.size() && in[0]==0) zeros++, in.erase(in.begin());
    fixed++;
  }

  for(i=in.size()-1;i>=0;i--){
    REP(j,i+1,in.size()){
      if( (in[i]^in[j]) < in[j] ) in[j] ^= in[i];
    }
  }

  rep(i,in.size()-1) in[in.size()-1] ^= in[i];
  rep(i,in.size()-1) in[i] ^= in[in.size()-1];

  rep(i,in.size()) res += in[i];
  rep(i,zeros) res += in[in.size()-1];

  return res;
}

};

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://rsujskf.blog32.fc2.com/tb.php/2300-b93e782f
この記事にトラックバックする(FC2ブログユーザー)

Appendix

Recent Articles

ブログ内検索

Ads


(プライバシーポリシー)
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。