Submission #1128954

#TimeUsernameProblemLanguageResultExecution timeMemory
1128954vladiliusDigital Circuit (IOI22_circuit)C++20
61 / 100
3035 ms32896 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define pb push_back
#define ff first
#define ss second
const int mod = 1000002022;

vector<vector<int>> g, dp;
vector<int> a;
int n, m;
bool ind;

void fill(int v){
    if (g[v].empty()) return;
    int k = (int) g[v].size(), pr = k;
    for (int i: g[v]){
        fill(i);
        pr = (1LL * pr * (dp[i][0] + dp[i][1])) % mod;
    }
    vector<vector<int>> f(k + 1, vector<int>(k + 1)); f[0][0] = 1;
    for (int i = 1; i <= k; i++){
        int u = g[v][i - 1];
        f[i][0] = (1LL * f[i - 1][0] * dp[u][0]) % mod;
        for (int j = 1; j <= k; j++){
            f[i][j] = (1LL * f[i - 1][j] * dp[u][0] + 1LL * f[i - 1][j - 1] * dp[u][1]) % mod;
        }
    }
    dp[v][1] = 0;
    for (int i = 1; i <= k; i++){
        dp[v][1] = (dp[v][1] + 1LL * i * f[k][i]) % mod;
    }
    dp[v][0] = (pr - dp[v][1]) % mod;
    if (dp[v][0] < 0) dp[v][0] += mod;
}

vector<int> P;
void dfs1(int v){
    P[v] = (int) g[v].size();
    if (!P[v]) P[v] = 1;
    for (int i: g[v]){
        dfs1(i);
        P[v] = (1LL * P[v] * P[i]) % mod;
    }
}

vector<int> f;
void dfs2(int v){
    for (int i: g[v]){
        int x = ((i == g[v][0]) ? P[g[v][1]] : P[g[v][0]]);
        f[i] = (1LL * f[v] * x) % mod;
        dfs2(i);
    }
}

struct node{
    int s, X;
};

vector<node> t;
vector<bool> p;

void build(int v, int tl, int tr){
    if (tl == tr){
        t[v].X = f[tl + n - 1];
        t[v].s = a[tl - 1] * t[v].X;
        return;
    }
    int tm = (tl + tr) / 2, vv = 2 * v;
    build(vv, tl, tm);
    build(vv + 1, tm + 1, tr);
    t[v].s = (t[vv].s + t[vv + 1].s) % mod;
    t[v].X = (t[vv].X + t[vv + 1].X) % mod;
}

void push(int& v){
    if (!p[v]) return;
    int vv = 2 * v;
    t[vv].s = (t[vv].X - t[vv].s) % mod;
    if (t[vv].s < 0) t[vv].s += mod;
    t[vv + 1].s = (t[vv + 1].X - t[vv + 1].s) % mod;
    if (t[vv + 1].s < 0) t[vv + 1].s += mod;
    p[vv] = !p[vv]; p[vv + 1] = !p[vv + 1];
    p[v] = 0;
}

void upd(int v, int tl, int tr, int& l, int& r){
    if (l > tr || r < tl) return;
    if (l <= tl && tr <= r){
        t[v].s = (t[v].X - t[v].s) % mod;
        if (t[v].s < 0) t[v].s += mod;
        p[v] = !p[v];
        return;
    }
    int tm = (tl + tr) / 2, vv = 2 * v;
    push(v);
    upd(vv, tl, tm, l, r);
    upd(vv + 1, tm + 1, tr, l, r);
    t[v].s = (t[vv].s + t[vv + 1].s) % mod;
}

void upd(int l, int r){
    upd(1, 1, m, l, r);
}

int count_ways(int l, int r){
    l -= n; r -= n;
    if (ind){
        l++; r++;
        upd(l, r);
        return t[1].s;
    }
    else {
        for (int i = l; i <= r; i++){
            a[i] = !a[i];
        }
        for (int i = n; i < n + m; i++){
            dp[i][1] = a[i - n];
            dp[i][0] = !dp[i][1];
        }
        fill(0);
        return dp[0][1];
    }
}

void init(int N, int M, vector<int> pr, vector<int> A){
    n = N; m = M; a = A;
    g.resize(n + m);
    for (int i = 1; i < n + m; i++){
        g[pr[i]].pb(i);
    }
    ind = 1;
    for (int i = 0; i < n; i++){
        if (g[i].size() != 2){
            ind = 0;
        }
    }
    dp.resize(n + m);
    for (int i = 0; i < dp.size(); i++){
        dp[i].resize(2);
    }
    
    if (ind){
        P.resize(n + m);
        dfs1(0);
        f.resize(n + m);
        f[0] = 1;
        dfs2(0);
        t.resize(4 * m);
        p.resize(4 * m);
        build(1, 1, m);
    }
}
#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...