Submission #870661

#TimeUsernameProblemLanguageResultExecution timeMemory
870661NonozeDigital Circuit (IOI22_circuit)C++17
22 / 100
3062 ms12788 KiB
#include "circuit.h" //#include "stub.cpp" #include <bits/stdc++.h> using namespace std; #define int long long const int MOD= 1000002022; struct node { node* left, *right; int allume, eteint; void update() { int comp=0; comp+=(left->eteint*right->allume)%MOD; comp+=(left->allume*right->eteint)%MOD; comp%=MOD; allume=comp+(left->allume*right->allume*2); eteint=comp+(left->eteint*right->eteint*2); allume%=MOD, eteint%=MOD; } }; /*int query(node* root, int left, int right, int qLeft, int qRight) { if (left>qRight || right<qLeft) return 0; if (left>=qLeft && right<=qRight) return root->sum; int mid=(left+right)/2; return query(root->left, left, mid, qLeft, qRight)+query(root->right, mid+1, right, qLeft, qRight); }*/ void update(node* root, int left, int right, int qLeft, int qRight) { if (left>qRight || right<qLeft) return; if (left==right) { root->allume^=1; root->eteint^=1; return; } int mid=(left+right)/2; update(root->left, left, mid, qLeft, qRight); update(root->right, mid+1, right, qLeft, qRight); root->update(); } void build(node* root, int left, int right, const vector<signed> &v) { if (left==right) { root->allume=v[left]; root->eteint=v[left]^1; return; } root->left=new node{NULL, NULL, 0, 0}; root->right=new node{NULL, NULL, 0, 0}; int mid=(left+right)/2; build(root->left, left, mid, v); build(root->right, mid+1, right, v); root->update(); } void destroy(node* root) { if (root->left) destroy(root->left); if (root->right) destroy(root->right); delete root; } vector<signed> a; vector<int> adj[100005]; int n, m; pair<int, int> dfs(int s) { if (s>=n) { return {a[s-n], a[s-n]^1}; } vector<int> dp(adj[s].size()+1, 0); dp[0]=1; for (auto u: adj[s]) { auto act=dfs(u); for (int i=dp.size()-1; i>=0; i--) { dp[i]=(dp[i]*act.second)%MOD; if (i>0) { dp[i]+=(dp[i-1]*act.first)%MOD; } dp[i]%=MOD; } } pair<int, int> ans={0, 0}; for (int i=1; i<(int)dp.size()-1; i++) { ans.first+=(dp[i]*i)%MOD; ans.second+=(dp[i]*(dp.size()-i-1)); ans.first%=MOD, ans.second%=MOD; } ans.first+=dp[dp.size()-1]*(dp.size()-1); ans.second+=dp[0]*(dp.size()-1); return {ans.first%MOD, ans.second%MOD}; } bool subtask5=false; node *root=new node{NULL, NULL, 0, 0}; #undef int void init(int N, int M, vector<int> p, vector<int> aa) { a=aa; n=N, m=M; for (int i=1; i<n+m; i++) { adj[p[i]].push_back(i); } if (m!=n+1) return; int power=1; while (power<m) power*=2; if (power!=m) return; subtask5=true; build(root, 0, m-1, a); } int count_ways(int L, int R) { #define int long long if (subtask5) { update(root, 0, m-1, L-n, R-n); return root->allume; } for (int i=L; i<=R; i++) { a[i-n]^=1; } return dfs(0).first; }
#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...