제출 #799426

#제출 시각아이디문제언어결과실행 시간메모리
799426JakobZorz디지털 회로 (IOI22_circuit)C++17
89 / 100
3016 ms23940 KiB
#include"circuit.h"
#include<vector>
#include<iostream>
using namespace std;
typedef long long ll;

const int MOD=1000002022;
const int TREE_SIZE=1<<18;

int parents[200000];
ll sub_mul[200000];
vector<int>children[200000];
int n,m;
ll vals[100000];

struct SegTree{
    vector<int>tree;
    vector<int>tree_val;
    vector<bool>lazy;
    
    void init_tree(int node,int l,int r){
        int m=(l+r)/2;
        if(m==l)
            return;
        
        init_tree(2*node,l,m);
        init_tree(2*node+1,m,r);
        tree[node]=tree[2*node]+tree[2*node+1];
        tree[node]%=MOD;
    }
    
    SegTree(ll*arr,int size){
        tree.resize(2*TREE_SIZE);
        tree_val.resize(2*TREE_SIZE);
        lazy.resize(2*TREE_SIZE);
        for(int i=0;i<size;i++)
            tree[TREE_SIZE+i]=arr[i];
        init_tree(1,0,TREE_SIZE);
    }
    
    int get(){
        return tree_val[1];
    }
    
    void push(int node,int l,int r){
        if(lazy[node]){
            lazy[node]=false;
            tree_val[node]=tree[node]+MOD-tree_val[node];
            tree_val[node]%=MOD;
            if(l<r-1){
                lazy[2*node]=!lazy[2*node];
                lazy[2*node+1]=!lazy[2*node+1];
            }
        }
    }
    
    void toggle(int node,int rl,int rr,int l,int r){
        push(node,l,r);
        
        if(rr<=l||r<=rl)
            return;
        
        if(rl<=l&&r<=rr){
            lazy[node]=true;
            push(node,l,r);
            return;
        }
        
        int m=(l+r)/2;
        toggle(2*node,rl,rr,l,m);
        toggle(2*node+1,rl,rr,m,r);
        
        tree_val[node]=tree_val[2*node]+tree_val[2*node+1];
        tree_val[node]%=MOD;
    }
};

SegTree*segtree;

void dfs2(int node){
    if(children[node].empty()){
        sub_mul[node]=1;
        return;
    }
    
    sub_mul[node]=children[node].size();
    for(int ch:children[node]){
        dfs2(ch);
        sub_mul[node]*=sub_mul[ch];
        sub_mul[node]%=MOD;
    }
}

void dfs3(int node,ll val){
    if(children[node].empty()){
        vals[node-n]=val;
        return;
    }
    
    for(int ch:children[node]){
        ll val2=val;
        for(int ch2:children[node]){
            if(ch2!=ch){
                val2*=sub_mul[ch2];
                val2%=MOD;
            }
        }
        dfs3(ch,val2);
    }
}

void init(int N, int M, std::vector<int> P, std::vector<int> A) {
    n=N;
    m=M;
    for(int i=0;i<n+m;i++){
        parents[i]=P[i];
        if(parents[i]!=-1)
            children[parents[i]].push_back(i);
    }
    
    dfs2(0);
    dfs3(0,1);
    
    segtree=new SegTree(vals,m);
    
    for(int i=0;i<(int)A.size();i++)
        if(A[i]==1)
            segtree->toggle(1,i,i+1,0,TREE_SIZE);
}

int count_ways(int L, int R) {
    L-=n;
    R-=n;
    segtree->toggle(1,L,R+1,0,TREE_SIZE);
    
    /*for(int i=0;i<m;i++)
        cout<<active[i]<<" ";
    cout<<"\n";
    for(int i=0;i<m;i++)
        cout<<vals[i]<<" ";
    cout<<"\n";*/
    
    
    return segtree->get();
}
#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...