Submission #1223808

#TimeUsernameProblemLanguageResultExecution timeMemory
1223808onbertDigital Circuit (IOI22_circuit)C++20
100 / 100
408 ms35876 KiB
#include "circuit.h"
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 2e5 + 5, maxN = 4e5 + 5, M = 1000002022;
int n, m;
int a[maxn];
vector<int> adj[maxn];

int comb[maxn];
void dfs1(int u) {
    comb[u] = max((int)adj[u].size(), (int)1);
    for (int v:adj[u]) {
        dfs1(v);
        comb[u] = comb[u] * comb[v] % M;
    }
}
int coeff[maxn];
void dfs2(int u) {
    int sz = adj[u].size();
    if (sz == 0) return;

    int pref[sz], suff[sz];
    pref[0] = comb[adj[u][0]], suff[sz-1] = comb[adj[u][sz-1]];
    for (int i=1;i<sz;i++) pref[i] = comb[adj[u][i]] * pref[i-1] % M;
    for (int i=sz-2;i>=0;i--) suff[i] = comb[adj[u][i]] * suff[i+1] % M;

    for (int i=0;i<sz;i++) {
        int v = adj[u][i];
        coeff[v] = coeff[u];
        if (i != 0) coeff[v] = coeff[v] * pref[i-1] % M;
        if (i != sz-1) coeff[v] = coeff[v] * suff[i+1] % M;
        dfs2(v);
    }
}

int seg[maxN], lazy[maxN];
void build(int id, int l, int r) {
    lazy[id] = 1;
    if (l == r) {
        if (a[l]) seg[id] = -coeff[l];
        else seg[id] = coeff[l];
        return;
    }
    int mid = (l+r)/2;
    build(id*2, l, mid); build(id*2+1, mid+1, r);
    seg[id] = seg[id*2] + seg[id*2+1];
}
void push(int id) {
    seg[id] *= lazy[id];
    if (id*2 < maxN) lazy[id*2] *= lazy[id];
    if (id*2+1 < maxN) lazy[id*2+1] *= lazy[id];
    lazy[id] = 1;
}
int qry(int id, int l, int r, int findl, int findr) {
    push(id);
    if (r < findl || findr < l) return 0;
    if (findl <= l && r <= findr) return seg[id];
    int mid = (l+r)/2;
    return qry(id*2, l, mid, findl, findr) + qry(id*2+1, mid+1, r, findl, findr);
}
void update(int id, int l, int r, int findl, int findr) {
    push(id);
    if (r < findl || findr < l) return;
    if (findl <= l && r <= findr) {
        lazy[id] *= -1;
        push(id);
        return;
    }
    int mid = (l+r)/2;
    update(id*2, l, mid, findl, findr);
    update(id*2+1, mid+1, r, findl, findr);
    seg[id] = seg[id*2] + seg[id*2+1];
}

int ans = 0;
void init(int32_t N, int32_t M, vector<int32_t> P, vector<int32_t> A) {
    n = N, m = M;
    for (int i=1;i<n + m;i++) adj[P[i]].push_back(i);
    for (int i=0;i<m;i++) a[n+i] = A[i];
    dfs1(0);
    coeff[0] = 1;
    dfs2(0);
    for (int i=0;i<m;i++) a[i] = a[i+n], coeff[i] = coeff[i+n];
    for (int i=0;i<m;i++) ans += a[i] * coeff[i];
    build(1, 0, m-1);
}

int32_t count_ways(int32_t L, int32_t R) {
    L -= n, R -= n;
    // cout << qry(L, R) << endl;
    ans += qry(1, 0, m-1, L, R);
    update(1, 0, m-1, L, R);
    return (ans % 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...