제출 #628553

#제출 시각아이디문제언어결과실행 시간메모리
628553600Mihnea디지털 회로 (IOI22_circuit)C++17
89 / 100
3069 ms24532 KiB
#include "circuit.h"
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const int MOD = 1000002022;

int add(int a, int b) {
  a += b;
  if (a >= MOD) return a - MOD;
  if (a < 0) return a + MOD;
  return a;
}

int mul(int a, int b) {
  return a * (ll) b % MOD;
}

void addup(int &a, int b) {
  a = add(a, b);
}

void mulup(int &a, int b) {
  a = mul(a, b);
}

struct Vertex {
  int s0, s1;
};

Vertex operator + (Vertex a, Vertex b) {
  return {add(a.s0, b.s0), add(a.s1, b.s1)};
}

vector<int> c, now;
int dim, subtract;
vector<Vertex> tree;
vector<int> lazy;

void build(int v, int tl, int tr) {
  lazy[v] = 0;

  if (tl == tr) {
    tree[v].s0 = now[tl] * c[tl];
    tree[v].s1 = (1 - now[tl]) * c[tl];
  } else {
    int tm = (tl + tr) / 2;
    build(2 * v, tl, tm);
    build(2 * v + 1, tm + 1, tr);
    tree[v] = tree[2 * v] + tree[2 * v + 1];
  }
}

void push(int v, int tl, int tr) {
  if (lazy[v]) {
    swap(tree[v].s0, tree[v].s1);
    if (tl < tr) lazy[2 * v] ^= 1, lazy[2 * v + 1] ^= 1;
    lazy[v] = 0;
  }
}

void op(int v, int tl, int tr, int l, int r) {
  push(v, tl, tr);
  if (tr < l || r < tl) return;
  if (l <= tl && tr <= r) {
    lazy[v] ^= 1;
    push(v, tl, tr);
    return;
  }
  int tm = (tl + tr) / 2;
  op(2 * v, tl, tm, l, r);
  op(2 * v + 1, tm + 1, tr, l, r);
  tree[v] = tree[2 * v] + tree[2 * v + 1];
}

void init(int n, int m, std::vector<int> par, std::vector<int> init) {
  dim = m;
  tree.resize(4 * dim + 7);
  lazy.resize(4 * dim + 7);
  subtract = n;
  c.resize(m, 0);
  ///cout << n << " " << m << " : " << (int) par.size() << " vs " << (int) init.size() << "\n";
  vector<vector<int>> g(n + m);
  vector<int> prod(n + m, 1);
  for (int i = 1; i < n + m; i++) {
    g[par[i]].push_back(i);
  }
  function<void(int)> build1 = [&] (int a) {
    if (g[a].empty()) return;
    prod[a] = (int) g[a].size();
    for (auto &b : g[a]) {
      build1(b);
      mulup(prod[a], prod[b]);
    }
  };
  now = init;
  function<void(int, int)> dfs = [&] (int a, int coef) {
    /// optimize this function
    for (int i = 0; i < (int) g[a].size(); i++) {
      int send = coef;
      for (int j = 0; j < (int) g[a].size(); j++) {
        if (i != j) {
          mulup(send, prod[g[a][j]]);
        }
      }
      dfs(g[a][i], send);
    }
    if (g[a].empty()) {
      assert(n + 0 <= a && a < n + m);
      c[a - n] = coef;
    }
  };
  build1(0);
  dfs(0, 1);
  build(1, 0, dim - 1);
}

int count_ways(int l, int r) {
  l -= subtract;
  r -= subtract;
  op(1, 0, dim - 1, l, r);
  push(1, 0, dim - 1);
  return tree[1].s0;
}


#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...