Submission #678455

#TimeUsernameProblemLanguageResultExecution timeMemory
678455silxikysBroken Device (JOI17_broken_device)C++17
100 / 100
831 ms2968 KiB
#include "Annalib.h"
#include <bits/stdc++.h>
using namespace std;

#define DEBUG(x) cerr << #x << ": " << x << '\n'
template <typename A, typename B>
ostream &operator<<(ostream &os, const pair<A, B> &p) {
  return os << '(' << p.first << ", " << p.second << ')';
}
template <typename T_container, typename T = typename enable_if<
                                    !is_same<T_container, string>::value,
                                    typename T_container::value_type>::type>
ostream &operator<<(ostream &os, const T_container &v) {
  os << '[';
  string sep;
  for (const T &x : v) os << sep << x, sep = ", ";
  return os << ']';
}

namespace ModInt { //{{{
  template<int MOD>
  struct mod_int {
    int val;

    operator int() const { return val; }
    mod_int() : val(0) {}
    mod_int(int _val) : val(_val % MOD) {}

    mod_int operator+() const {
      return mod_int(val);
    }
    mod_int operator-() const {
      return mod_int(MOD-val);
    }
    mod_int inverse() const {
      assert(val != 0);
      return *this ^ (MOD - 2);
    }

    mod_int& operator+=(const mod_int& b) {
      val += b.val;
      if (val >= MOD) val -= MOD;
      return *this;
    }
    mod_int& operator-=(const mod_int& b) {
      return *this += -b;
    }
    mod_int& operator*=(const mod_int& b) {
      val = (1LL*val*b.val) % MOD;
      return *this;
    }
    mod_int& operator/=(const mod_int& b) {
      val = (1LL*val*b.inverse().val) % MOD;
      return *this;
    }

    mod_int& operator+=(int b) {
      return *this += mod_int(b);
    }
    mod_int& operator-=(int b) {
      return *this -= mod_int(b);
    }
    mod_int& operator*=(int b) {
      return *this *= mod_int(b);
    }
    mod_int& operator/=(int b) {
      return *this /= mod_int(b);
    }

    friend mod_int operator+(const mod_int& a, const mod_int& b) {
      mod_int c = a; c += b;
      return c;
    }
    friend mod_int operator-(const mod_int& a, const mod_int& b) {
      mod_int c = a; c -= b;
      return c;
    }
    friend mod_int operator*(const mod_int& a, const mod_int& b) {
      mod_int c = a; c *= b;
      return c;
    }
    friend mod_int operator/(const mod_int& a, const mod_int& b) {
      mod_int c = a; c /= b;
      return c;
    }

    friend mod_int operator+(const mod_int& a, int b) {
      return a + mod_int(b);
    }
    friend mod_int operator-(const mod_int& a, int b) {
      return a - mod_int(b);
    }
    friend mod_int operator*(const mod_int& a, int b) {
      return a * mod_int(b);
    }
    friend mod_int operator/(const mod_int& a, int b) {
      return a / mod_int(b);
    }
    friend mod_int operator+(int a, const mod_int& b) {
      return mod_int(a) + b;
    }
    friend mod_int operator-(int a, const mod_int& b) {
      return mod_int(a) - b;
    }
    friend mod_int operator*(int a, const mod_int& b) {
      return mod_int(a) * b;
    }
    friend mod_int operator/(int a, const mod_int& b) {
      return mod_int(a) / b;
    }

    friend mod_int operator^(mod_int a, int b) {
      mod_int res(1);
      while (b > 0) {
        if (b&1) res *= a;
        a *= a;
        b >>= 1;
      }
      return res;
    }

    friend ostream& operator<<(ostream& o, const mod_int& x) {
      return o << x.val;
    };
    friend istream& operator>>(istream& i, mod_int& x) {
      return i >> x.val;
    }
  };
} //}}}
using mint = ModInt::mod_int<2>;

int gauss (vector<vector<mint>> a, vector<mint> & ans) {
  int n = (int) a.size();
  int m = (int) a[0].size() - 1;

  vector<int> where (m, -1);
  for (int col=0, row=0; col<m && row<n; ++col) {
    int sel = row;
    for (int i=row; i<n; ++i)
      if (a[i][col] > a[sel][col])
        sel = i;
    if (a[sel][col] == 0)
      continue;
    for (int i=col; i<=m; ++i)
      swap (a[sel][i], a[row][i]);
    where[col] = row;

    for (int i=0; i<n; ++i)
      if (i != row) {
        assert(a[row][col] == 1);
        // mint c = a[i][col] / a[row][col];
        mint c = a[i][col];
        for (int j=col; j<=m; ++j)
          a[i][j] -= a[row][j] * c;
      }
    ++row;
  }

  ans.assign (m, 0);
  for (int i=0; i<m; ++i)
    if (where[i] != -1)
      ans[i] = a[where[i]][m] / a[where[i]][i];
  for (int i=0; i<n; ++i) {
    mint sum = 0;
    for (int j=0; j<m; ++j)
      sum += ans[j] * a[i][j];
    if (sum - a[i][m] > 0)
      return 0;
  }

  for (int i=0; i<m; ++i)
    if (where[i] == -1)
      return 2;
  return 1;
}

void Anna( int N, long long X, int K, int P[] ){
  std::mt19937 rng(6969);
  const int MX = 60;
  int A[MX][N];
  for (int i = 0; i < MX; i++) {
    for (int j = 0; j < N; j++) {
      A[i][j] = rng() & 1;
    }
  }
  vector<bool> broken(N, false);
  for (int i = 0; i < K; i++) broken[P[i]] = true;
  vector<vector<mint>> a(MX, vector<mint>(N+1, 0));
  for (int j = 0; j < N; j++) {
    if (broken[j]) continue;
    for (int i = 0; i < MX; i++) a[i][j] = A[i][j];
  }
  for (int i = 0; i < MX; i++) a[i][N] = (X >> i) & 1;
  vector<mint> ans(N);
  int sol = gauss(a, ans);
  assert(sol > 0);

  for( int i = 0; i < N; i++ ){
    if (broken[i]) Set(i, 0);
    else Set(i, ans[i]);
  }
}
#include "Brunolib.h"
#include <bits/stdc++.h>
using namespace std;

long long Bruno( int N, int A[] ){
  std::mt19937 rng(6969);
  const int MX = 60;
  int B[MX][N];
  for (int i = 0; i < MX; i++) {
    for (int j = 0; j < N; j++) {
      B[i][j] = rng() & 1;
    }
  }

  long long ans = 0;
  for (int j = 0; j < N; j++) if (A[j]) {
    for (int i = 0; i < MX; i++) {
      if (B[i][j]) ans ^= 1LL << i;
    }
  }

  return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...