Submission #1182310

#TimeUsernameProblemLanguageResultExecution timeMemory
1182310PagodePaivaDigital Circuit (IOI22_circuit)C++20
100 / 100
423 ms33212 KiB
#include "circuit.h"
#include<bits/stdc++.h>
#include <vector>
#define ll long long

using namespace std;

const ll mod = 1000002022; 
const int N = 300010;
vector <int> g[N];
ll tot[N], c[N];
int pai[N];
vector <int> start;
int n;

struct Segtree{
    struct Node{
        ll val, soma;
        int lazy;
    } tree[4*N], nulo;
    Node join(Node a, Node b){
        Node res;
        res.val = a.val+b.val;
        res.val %= mod;
        res.soma = a.soma+b.soma;
        res.soma %= mod;
        res.lazy = 0;
        return res;
    }
    void unlazy(int node, int l, int r){
        if(!tree[node].lazy) return;
        tree[node].val = tree[node].soma - tree[node].val;
        tree[node].val %= mod;
        tree[node].val += mod;
        tree[node].val %= mod;
        if(l != r){
            tree[2*node].lazy ^= tree[node].lazy;
            tree[2*node+1].lazy ^= tree[node].lazy;
        }
        tree[node].lazy = 0;
    }
    void build(int node, int l, int r){
        if(node == 1){
            nulo.val = nulo.soma = 0;
            nulo.lazy = 0;
        }
        tree[node].lazy = 0;
        if(l == r){
            tree[node].soma = c[l+n-1];
            tree[node].val = (start[l-1] == 1 ? tree[node].soma : 0);
            return;
        }
        int mid = (l+r)/2;
        build(2*node, l, mid);
        build(2*node+1, mid+1, r);
        tree[node] = join(tree[2*node], tree[2*node+1]);
        return;
    }
    void update(int node, int l, int r, int tl, int tr){
        unlazy(node, tl, tr);
        if(l > tr or tl > r) return;
        if(l <= tl and tr <= r){
            tree[node].lazy ^= 1;
            unlazy(node, tl, tr);
            return;
        }
        int mid =(tl+tr)/2;
        update(2*node, l, r, tl, mid);
        update(2*node+1, l, r, mid+1, tr);
        tree[node] = join(tree[2*node], tree[2*node+1]);
        return;
    }
    Node query(int node, int l, int r, int tl, int tr){
        unlazy(node, tl ,tr);
        if(l > tr or tl > r) return nulo;
        if(l <= tl and tr <= r) return tree[node];
        int mid = (tl+tr)/2;
        return join(query(2*node, l, r, tl, mid), query(2*node+1, l, r, mid+1, tr));
    }
} seg;

void dfs(int v, int p){
    if(g[v].size() == 0){
        pai[v] = p;
        tot[v] = 1;
        return;
    }
    pai[v] = p;
    tot[v] = 1;
    for(auto x : g[v]){
        dfs(x, v);
        tot[v] *= tot[x];
        tot[v] %= mod;
    }
    tot[v] *= (ll) g[v].size();
    tot[v] %= mod;
    return;
}

ll pref[N], suf[N];

void dfs2(int v, int p){
    // c[v] = mul(dividir(tot[p], mul(g[p].size(), tot[v])), c[p]);
    pref[0] = 1;
    suf[g[v].size()+1] = 1;
    for(int i = 1;i <= g[v].size();i++){
        int x = g[v][i-1];
        pref[i] = (pref[i-1]*tot[x]) % mod;
    }
    for(int i = g[v].size();i > 0;i--){
        int x = g[v][i-1];
        suf[i] = (suf[i+1]*tot[x]) % mod;
    }
    for(int i = 1;i <= g[v].size();i++){
        int x = g[v][i-1];
        c[x] = (pref[i-1]*suf[i+1])% mod;
        c[x] *= c[v];
        c[x] %= mod;
    }
    for(auto x : g[v]){
        dfs2(x, v);
    }
    return;
}

int m;

void init(int N, int M, std::vector<int> P, std::vector<int> A) {
    start = A;
    m = M;
    n = N;
    for(int i = 1;i < P.size();i++){
        g[P[i]].push_back(i);
    }
    dfs(0, 0);
    c[0] = 1;
    dfs2(0, 0);
    /*for(int i = 0;i < n+m;i++){
        cout << tot[i] << ' ' << c[i] << '\n';
    }
    cout << '\n';*/
    seg.build(1, 1, M);
}

int count_ways(int l, int r) {
    l -= n-1;
    r -= n-1;
    seg.update(1, l, r, 1, m);
    return seg.query(1, 1, m, 1, m).val;
}
#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...