Entries

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

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

コメント

コメントの投稿

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

トラックバック

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

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

Source

TopCoder SRM564 DIV1 HARD (850pt)
Problem Statement

問題概要

m要素 (50以下) の正整数列Aと正整数Nが与えられるので,以下の条件を満たす非負整数列Xは何個存在するかをmod 1000000007で求める問題.
 X[1] XOR X[2] XOR ... XOR X[m] = N (XORはビットごとにXOR)
 0 ≤ X[k] ≤ A[k]
各整数は10^9以下.

解法

一番大きいXの要素の最上位ビットを使うかどうかで場合分けをする.
最上位ビットを使う場合は,そのビットと,Nの対応するビットを反転させて1つ合計ビットの少ない問題に帰着される.
最上位ビットを使わない場合は,その要素は,最上位ビット以外は自由に設定できる.
ので,他要素のXORの最上位ビットがNと一致していれば,後はその要素で調整できる.
なので,最上位ビットだけを状態としてDPして数えれば良い.
小さい状態に帰着していって,すべてのビットがなくなった場合,N=0のときのみ1つ答えがあるのを忘れないこと.(忘れてしまった)

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 M 1000000007
#define ll long long

class DefectiveAddition {
public:
int count(vector <int> in, int n) {
  int i, j, k, s, bt;
  ll res = 0;
  ll dp[2], next[2];

  for(;;){
    sort(in.begin(), in.end());
    while(in.size() && in[0]==0) in.erase(in.begin());
    if(!in.size()){
      if(n==0) res++;
      break;
    }

    s = in.size();
    for(bt = 30; bt >= 0; bt--) if(in[s-1] & 1<<bt) break;
    REP(i,bt+1,31) if(n & 1<<i) break;
    if(i<31) break;

    dp[0] = dp[1] = 0;
    if(n&1<<bt) dp[1]++; else dp[0]++;
    rep(i,s-1){
      next[0] = next[1] = 0;
      if(in[i]&1<<bt){
        next[0] += (dp[0] * (1<<bt));
        next[1] += (dp[1] * (1<<bt));
        next[0] += (dp[1] * (in[i]-(1<<bt)+1));
        next[1] += (dp[0] * (in[i]-(1<<bt)+1));
      } else {
        next[0] += (dp[0] * (in[i]+1));
        next[1] += (dp[1] * (in[i]+1));
      }
      dp[0] = next[0] % M;
      dp[1] = next[1] % M;
    }

    res += dp[0];
    in[s-1] ^= (1<<bt);
    n ^= (1<<bt);
  }

  res %= M;
  return res;
}

};

コメント

コメントの投稿

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

トラックバック

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

Appendix

Recent Articles

ブログ内検索

Ads


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