Submission #1220186

#TimeUsernameProblemLanguageResultExecution timeMemory
1220186banganDigital Circuit (IOI22_circuit)C++20
100 / 100
391 ms36428 KiB
#include "circuit.h"

// #include <vector>
#include <bits/stdc++.h>

using i64 = long long;

constexpr int mod = 1'000'002'022;

int n, m;
std::vector<int> p, a;
std::vector<std::vector<int>> inp;

std::vector<int> sub;
std::vector<int> cof;

void calc_sub(int v) {
  if (v < n) {
    sub[v] = inp[v].size();
  } else {
    sub[v] = 1;
  }

  for (int u : inp[v]) {
    calc_sub(u);
    sub[v] = 1ll * sub[v] * sub[u] % mod;
  }
}

void calc_cof(int v) {
  auto &t = inp[v];
  int size = t.size();

  std::vector<int> pre(size + 1);
  pre[0] = 1;

  for (int i = 1; i <= size; i++) {
    pre[i] = 1ll * pre[i - 1] * sub[t[i - 1]] % mod;
  }

  std::vector<int> suf(size + 1);
  suf[size] = 1;

  for (int i = size - 1; i >= 0; i--) {
    suf[i] = 1ll * suf[i + 1] * sub[t[i]] % mod;
  }

  for (int i = 0; i < size; i++) {
    int u = t[i];
    cof[u] = 1ll * pre[i] * suf[i + 1] % mod
      * cof[v] % mod;
    
    calc_cof(u);
  }
}

std::vector<std::array<int, 2>> sum;
std::vector<int> lazy;

#define LC (2 * v)
#define RC (2 * v + 1)
#define mid ((l + r) / 2)

void push(int v) {
  if (lazy[v] == 1) {
    std::swap(sum[v][0], sum[v][1]);
  }

  if (LC < 4 * m) {
    lazy[LC] ^= lazy[v];
  }
  if (RC < 4 * m) {
    lazy[RC] ^= lazy[v];
  }
  lazy[v] = 0;
}

void pull(int v) {
  push(v);
  push(LC);
  push(RC);
  sum[v][0] = (sum[LC][0] + sum[RC][0]) % mod;
  sum[v][1] = (sum[LC][1] + sum[RC][1]) % mod;
}

void add(int i, int t, int x, int v = 1, int l = 0, int r = m) {
  if (r - l == 1) {
    sum[v][t] = x;
    return;
  }

  if (i < mid) {
    add(i, t, x, LC, l, mid);
  } else {
    add(i, t, x, RC, mid, r);
  }
  pull(v);
}

void invert(int s, int e, int v = 1, int l = 0, int r = m) {
  push(v);
  if (s <= l && r <= e) {
    lazy[v] ^= 1;
    push(v);
    return;
  }

  if (s < mid) {
    invert(s, e, LC, l, mid);
  }
  if (e > mid) {
    invert(s, e, RC, mid, r);
  }
  pull(v);
}

void init(int N, int M, std::vector<int> P, std::vector<int> A) {
  n = N;
  m = M;
  p = P;
  a = A;

  inp.resize(n + m);
  for (int i = 1; i < n + m; i++) {
    inp[p[i]].push_back(i);
  }

  sub.resize(n + m);
  calc_sub(0);

  cof.resize(n + m);
  cof[0] = 1;
  calc_cof(0);

  // std::cerr << "cofs:\n";
  // for (int i = 0; i < n + m; i++) {
  //   std::cerr << "cof[" << i << "] = " << cof[i] << '\n';
  // }

  sum.resize(4 * m);
  lazy.resize(4 * m);

  for (int i = 0; i < m; i++) {
    add(i, a[i], cof[i + n]);
  }
}

int count_ways(int L, int R) {
  invert(L - n, R - n + 1);
  return sum[1][1];
}
#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...