Submission #1071769

#TimeUsernameProblemLanguageResultExecution timeMemory
1071769UnforgettableplDigital Circuit (IOI22_circuit)C++17
100 / 100
850 ms33700 KiB
#include "circuit.h"
#include <bits/stdc++.h>
using namespace std;

const long long modulo = 1e9+2022;

struct segtree {
    vector<pair<long long,long long>> tree;
    int N;
    vector<bool> lazy;
    segtree(){}
    void build(int x,int L,int R,vector<long long> &arr,vector<int> &A) {
        if(L==R) {
            if(A[L-1]) tree[x].first=arr[L-1];
            else tree[x].second=arr[L-1];
            return;
        }
        int mid = (L+R)/2;
        build(2*x,L,mid,arr,A);
        build(2*x+1,mid+1,R,arr,A);
        tree[x].first=(tree[2*x].first+tree[2*x+1].first)%modulo;
        tree[x].second=(tree[2*x].second+tree[2*x+1].second)%modulo;
    }
    segtree(int N,vector<long long> &arr,vector<int> &A):tree(4*N),N(N),lazy(4*N) {
        build(1,1,N,arr,A);
    }
    void update(int x,int L,int R,int qL,int qR) {
        if(lazy[x]) {
            swap(tree[x].first,tree[x].second);
            lazy[x]=false;
            if(L!=R) {
                lazy[2*x]=!lazy[2*x];
                lazy[2*x+1]=!lazy[2*x+1];
            }
        }
        if(qR<L or R<qL)return;
        if(qL<=L and R<=qR) {
            swap(tree[x].first,tree[x].second);
            if(L!=R) {
                lazy[2*x]=!lazy[2*x];
                lazy[2*x+1]=!lazy[2*x+1];
            }
            return;
        }
        int mid = (L+R)/2;
        update(2*x,L,mid,qL,qR);
        update(2*x+1,mid+1,R,qL,qR);
        tree[x].first=(tree[2*x].first+tree[2*x+1].first)%modulo;
        tree[x].second=(tree[2*x].second+tree[2*x+1].second)%modulo;
    }
    void update(int L,int R) {
        update(1,1,N,L+1,R+1);
    }
    long long get() {
        return tree[1].first;
    }
};

namespace {
    int N,M;
    vector<int> A;
    vector<long long> arr;
    segtree seg;
}

void init(int N,int M,vector<int> P,vector<int> A){
    ::N = N;
    ::M = M;
    ::A = A;
    arr = vector<long long>(M);
    vector<vector<int>> adj(N);
    vector<vector<pair<long long,long long>>> ways(N);
    for(int i=1;i<N+M;i++){adj[P[i]].emplace_back(i);ways[P[i]].emplace_back(1,1);}
    {
        function<long long(int)> dfs = [&](int x){
            if(x>=N)return 1ll;
            long long tot_ways = adj[x].size();
            for(int i=0;i<adj[x].size();i++) {
                ways[x][i].first=ways[x][i].second=dfs(adj[x][i]);
                tot_ways=(tot_ways*ways[x][i].first)%modulo;
                if(i)ways[x][i].first=(ways[x][i].first*ways[x][i-1].first)%modulo;
            }
            for(int i=adj[x].size()-2;i>=0;i--)ways[x][i].second=(ways[x][i].second*ways[x][i+1].second)%modulo;
            return tot_ways;
        };
        dfs(0);
    }
    {
        function<void(int,long long)> dfs = [&](int x,long long offset) {
            if(x>=N) {
                arr[x-N]=offset;
                return;
            }
            for(int i=0;i<adj[x].size();i++) {
                long long tot = offset;
                if(i)tot=(tot*ways[x][i-1].first)%modulo;
                if(i!=adj[x].size()-1)tot=(tot*ways[x][i+1].second)%modulo;
                dfs(adj[x][i],tot);
            }
        };
        dfs(0,1);
    }
    seg = segtree(M,arr,A);
}

int count_ways(int L,int R){
    L-=N;R-=N;
    seg.update(L,R);
    return seg.get();
}

Compilation message (stderr)

circuit.cpp: In lambda function:
circuit.cpp:78:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   78 |             for(int i=0;i<adj[x].size();i++) {
      |                         ~^~~~~~~~~~~~~~
circuit.cpp: In lambda function:
circuit.cpp:94:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   94 |             for(int i=0;i<adj[x].size();i++) {
      |                         ~^~~~~~~~~~~~~~
circuit.cpp:97:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   97 |                 if(i!=adj[x].size()-1)tot=(tot*ways[x][i+1].second)%modulo;
      |                    ~^~~~~~~~~~~~~~~~~
#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...