Submission #634593

#TimeUsernameProblemLanguageResultExecution timeMemory
634593JeanBombeurDigital Circuit (IOI22_circuit)C++17
100 / 100
1137 ms41288 KiB
#include "circuit.h" #include <vector> #include <cstdio> using namespace std; // <|°_°|> // Jean Bombeur & M. Broccoli // The hardest choices require the strongest wills // What is better - to be born good, or to overcome your evil nature with great effort ? const int MOD = (1000002022); const int MAX_NODES = (2e5); const int LOG = (17); const int SIZE = (1 << LOG); struct node { int val = 0, inv = 0, flag = 0; }; node operator+(node a, node b) { return {a.val + b.val >= MOD ? a.val + b.val - MOD : a.val + b.val, a.inv + b.inv >= MOD ? a.inv + b.inv - MOD : a.inv + b.inv, 0}; } vector <int> Adj[MAX_NODES]; long long Sz[MAX_NODES]; node Tree[2 * SIZE]; int nbThresholds; int DfsSz(int node) { Sz[node] = Adj[node].size() + Adj[node].empty(); for (int dest : Adj[node]) Sz[node] *= DfsSz(dest), Sz[node] %= MOD; return Sz[node]; } void DfsSet(int node, long long value) { if (Adj[node].empty()) Tree[SIZE + node - nbThresholds] = {0, value, 0}; vector <long long> ProdPref (1, 1); vector <long long> ProdSuff (1, 1); int sz = Adj[node].size(); for (int i = 0; i < sz; i ++) { ProdPref.push_back((ProdPref.back() * Sz[Adj[node][i]]) % MOD); } for (int i = sz - 1; i >= 0; i --) { ProdSuff.push_back((ProdSuff.back() * Sz[Adj[node][i]]) % MOD); } for (int i = 0; i < sz; i ++) { DfsSet(Adj[node][i], (((value * ProdPref[i]) % MOD) * ProdSuff[sz - i - 1]) % MOD); } return; } void Push(int node) { Tree[node].flag = 0; swap(Tree[node].val, Tree[node].inv); if (node < SIZE) Tree[2 * node].flag ^= 1, Tree[2 * node + 1].flag ^= 1; return; } void Toggle(int node, int qleft, int qright, int left = 0, int right = SIZE) { if (Tree[node].flag) Push(node); if (qright <= left || right <= qleft) return; if (qleft <= left && right <= qright) { Push(node); return; } int mid = (left + right) >> 1; Toggle(2 * node, qleft, qright, left, mid); Toggle(2 * node + 1, qleft, qright, mid, right); Tree[node] = Tree[2 * node] + Tree[2 * node + 1]; return; } void init(int nbNodes, int nbSources, vector <int> Parent, vector <int> States) { nbThresholds = nbNodes; for (int i = 1; i < nbThresholds + nbSources; i ++) { Adj[Parent[i]].push_back(i); } DfsSz(0); DfsSet(0, 1); for (int i = 0; i < nbSources; i ++) { if (States[i]) swap(Tree[i + SIZE].val, Tree[i + SIZE].inv); } for (int i = SIZE - 1; i; i --) { Tree[i] = Tree[2 * i] + Tree[2 * i + 1]; } return; } int count_ways(int left, int right) { Toggle(1, left - nbThresholds, (++ right) - nbThresholds); return Tree[1].val; }

Compilation message (stderr)

circuit.cpp: In function 'void DfsSet(int, long long int)':
circuit.cpp:44:48: warning: narrowing conversion of 'value' from 'long long int' to 'int' [-Wnarrowing]
   44 |         Tree[SIZE + node - nbThresholds] = {0, value, 0};
      |                                                ^~~~~
#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...