Submission #652962

#TimeUsernameProblemLanguageResultExecution timeMemory
652962grtDigital Circuit (IOI22_circuit)C++17
100 / 100
2552 ms41652 KiB
//GRT_2018
#include <bits/stdc++.h>
#define PB push_back
#define ST first
#define ND second
//mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());

using namespace std;

using ll = long long;
using pi = pair<int,int>;
using vi = vector<int>;

const int nax = 200 * 1000 + 10;
const int mod = 1e9 + 2022;
vi V[nax];
int sz[nax];
int val[nax];
int inner;

void dfs(int x) {
        sz[x] = 1;
        for(int nbh : V[x]) {
                dfs(nbh);
                sz[x] = ((ll)sz[x] * sz[nbh]) % mod;
        }
        sz[x] = ((ll)sz[x] * max(1, (int)V[x].size())) % mod;
        cerr << x << " -> " << sz[x] << endl;
}

int n;

void dfs2(int x, int cont) {
        vi pref((int)V[x].size() + 2), suf((int)V[x].size() + 2);
        pref[0] = 1; suf[(int)V[x].size() + 1] = 1;
        for(int i = 1; i <= (int)V[x].size(); ++i) {
                pref[i] = ((ll)pref[i - 1] * sz[V[x][i - 1]]) % mod;
        }
        for(int i = (int)V[x].size(); i >= 1; --i) {
                suf[i] = ((ll)suf[i + 1] * sz[V[x][i - 1]]) % mod;
        }
        for(int i = 1; i <= (int)V[x].size(); ++i) {
                int nbh = V[x][i - 1];
                ll v = ((ll)pref[i - 1] * suf[i + 1]) % mod;
                dfs2(nbh, (v * cont) % mod);
        }
        if(x >= inner) {
                val[x - inner] = cont;
                cerr << x << ": " << cont << "\n";
        }
}

struct Node {
        int f, sum;
        bool rev;
};

Node T[(1 << 19)];

void pull(int v) {
        T[v].sum = (T[v << 1].sum + T[v << 1 | 1].sum) % mod;
        T[v].f = (T[v << 1].f + T[v << 1 | 1].f) % mod;
}

void build(vi &A, int l = 0, int r = n - 1, int v = 1) {
        if(l == r) {
                T[v].f = A[l] * val[l];
                T[v].sum = val[l];
                T[v].rev = 0;
                return;
        }
        int mid = (l + r) >> 1;
        build(A, l, mid, v << 1);
        build(A, mid + 1, r, v << 1 | 1);
        pull(v);
        T[v].rev = 0;
}

void putTag(int v) {
        T[v].f = (T[v].sum - T[v].f) % mod;
        T[v].rev ^= 1;
}

void push(int v) {
        if(!T[v].rev) return;
        putTag(v << 1);
        putTag(v << 1 | 1);
        T[v].rev = 0;
}

void upd(int a, int b, int l = 0, int r = n - 1, int v = 1) {
        if(a <= l && r <= b) {
                putTag(v);
                return;
        }
        int mid = (l + r) >> 1;
        push(v);
        if(a <= mid) upd(a, b, l, mid, v << 1);
        if(mid < b) upd(a, b, mid + 1, r, v << 1 | 1);
        pull(v);
}

void init(int N, int M, vi P, vi A) {
        inner = N;
        n = M;
        for(int i = 1; i < N + M; ++i) {
                V[P[i]].PB(i);
        }
        dfs(0);
        dfs2(0, 1);
        build(A);
}

int count_ways(int l, int r) {

        upd(l - inner, r - inner);
        int w = T[1].f;
        if(w < 0) w += mod;
        return w;
}
#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...