結果

問題 No.5001 排他的論理和でランニング
ユーザー pekempey
提出日時 2018-03-17 00:25:55
言語 C++11(廃止可能性あり)
(gcc 13.3.0)
結果
AC  
実行時間 634 ms / 1,500 ms
コード長 1,618 bytes
コンパイル時間 411 ms
実行使用メモリ 63,092 KB
スコア 52,428,750
最終ジャッジ日時 2020-03-12 19:45:12
ジャッジサーバーID
(参考情報)
judge10 /
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 50
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <map>
#include <set>

using namespace std;

const int N = 1e5;

int n, m;
int a[N];
int b[N];
set<int> used[N];

void merge(set<int> &a, set<int> &b) {
  for (int x : b) {
    if (a.count(x)) {
      a.erase(x);
    } else {
      a.insert(x);
    }
  }
}

void swap_row(int i, int j) {
  swap(a[i], a[j]);
  swap(used[i], used[j]);
}

// i -> j
void add_row(int i, int j) {
  a[j] ^= a[i];
  merge(used[j], used[i]);
}

int gauss() {
  int r = 0;
  for (int j = 20; j >= 0; j--) {
    int p = -1;
    for (int i = r; i < n; i++) {
      if (a[i] >> j & 1) {
        p = i;
        break;
      }
    }
    if (p == -1) continue;
    swap_row(r, p);
    for (int i = r + 1; i < n; i++) {
      if (a[i] >> j & 1) {
        add_row(r, i);
      }
    }
    r++;
  }
  return r;
}

void answer(set<int> a) {
  bool fst = false;
  for (int x : a) {
    if (fst) {
      cout << ' ';
    }
    cout << b[x];
    fst = true;
  }
  cout << endl;
  exit(0);
}

int main() {
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    used[i].insert(i);
    b[i] = a[i];
  }
  int r = gauss();

  set<int> res;
  int curr = 0;
  for (int i = 0; i < r; i++) {
    if ((curr ^ a[i]) > curr) {
      merge(res, used[i]);
      curr ^= a[i];
    }
  }
  cerr << curr << endl;
  if (res.size() == m) {
    answer(res);
  }
  cerr << res.size() << endl;
  for (int i = r; i < n; i++) {
    merge(res, used[i]);
    if (res.size() == m) {
      answer(res);
    }
    if (res.size() > m) {
      merge(res, used[i]);
    }
  }
  abort();
}
0