Submission #786444

#TimeUsernameProblemLanguageResultExecution timeMemory
786444vjudge1Digital Circuit (IOI22_circuit)C++17
23 / 100
3057 ms10424 KiB
#include "circuit.h"
#include <bits/stdc++.h>
using namespace std;
constexpr int mod = 1000002022;
int N, M;
vector<int> P, A, st, lazy, len;
vector<vector<int>> ch;
int add(int a, int b) {
    int c = a + b;
    if (c >= mod) {
        c -= mod;
    }
    return c;
}
int mul(int a, int b) {
    return 1LL * a * b % mod;
}
int sub(int a, int b) {
    int c = a - b;
    if (c < 0) {
        c += mod;
    }
    return c;
}
int cont;
bool bintree;
void apply(int p, int z) {
    if (z == 0) {
        return;
    }
    st[p] = len[p] - st[p];
    lazy[p] ^= 1;
}
void pull(int p) {
    st[p] = st[p * 2] + st[p * 2 + 1];
}
void push(int p) {
    apply(p * 2, lazy[p]);
    apply(p * 2 + 1, lazy[p]);
    lazy[p] = 0;
}
void update(int p, int l, int r, int L, int R) {
    if (R <= l || r <= L) {
        return;
    }
    if (L <= l && r <= R) {
        apply(p, 1);
        return;
    }
    int m = (l + r) / 2;
    push(p);
    update(p * 2, l, m, L, R);
    update(p * 2 + 1, m, r, L, R);
    pull(p);
}
void init(int n, int m, vector<int> p, vector<int> a) {
    N = n, M = m;
    P = p, A = a;
    ch.resize(N);
    for (int i = 1; i < N + M; i++) {
        ch[P[i]].push_back(i);
    }
    bintree = 0;
    if (N + 1 == M && __builtin_popcount(M) == 1) {
        bintree = 1;
        for (int i = 1; i < N + M; i++) {
            if (P[i] != (i - 1) / 2) {
                bintree = 0;
            }
        }
        if (bintree) {
            int lg = __lg(M);
            cont = 1;
            int s = 1;
            for (int i = 0; i < lg; i++) {
                cont = mul(cont, s);
                s = mul(2, mul(s, s));
            }
            st.resize(2 * M);
            len.resize(2 * M);
            lazy.resize(2 * M);
            for (int i = 0; i < M; i++) {
                st[i + M] = A[i];
                len[i + M] = 1;
            }
            for (int i = M - 1; i; i--) {
                st[i] = st[i * 2] + st[i * 2 + 1];
                len[i] = len[i * 2] + len[i * 2 + 1];
            }
        }
    }
}
int count_ways(int L, int R) {
    if (bintree) {
        update(1, 0, M, L - N, R - N + 1);
        return mul(st[1], cont);
    }
    for (int i = L; i <= R; i++) {
        A[i - N] ^= 1;
    }
    vector<int> tot(N + M), on(N + M), off(N + M);
    for (int i = N + M - 1; i >= 0; i--) {
        if (i >= N) {
            tot[i] = 1;
            if (A[i - N] == 0) {
                off[i] = 1;
            } else {
                on[i] = 1;
            }
        } else {
            int x = ch[i][0];
            int y = ch[i][1];
            tot[i] = mul(2, mul(tot[x], tot[y]));
            on[i] = add(mul(tot[x], on[y]), mul(tot[y], on[x]));
            off[i] = sub(tot[i], on[i]);
        }
    }
    return on[0];
}
#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...