Submission #1063360

#TimeUsernameProblemLanguageResultExecution timeMemory
1063360jer033Digital Circuit (IOI22_circuit)C++17
100 / 100
803 ms24512 KiB
#include "circuit.h" #include <vector> #include <bits/stdc++.h> using namespace std; using ll = long long; const ll MOD = 1'000'002'022; const ll totient = 497758632;//a^(totient-1) = inv(a) int n, m; vector<ll> storage;//When you call the constructor, make sure that everything is reduced modulo MOD vector<int> a; ll pow(ll a, ll b) { if (b==0ll) return 1; ll c = pow(a, b/2ll); c = (c*c)%MOD; if (((b/2ll)*(2ll)) != b)//b is odd c = (c*a)%MOD; return c; } ll inv(ll a) { return pow(a, totient-1ll); } class Lazy{ public: int L, R; ll total_sum; ll active;//MAKE SURE THAT THIS IS ALWAYS ACCURATE bool flip;//When I need to flip, I don't need to flip myself, I need to flip my children only Lazy* left; Lazy* right; Lazy() { L = 0; R = 0; total_sum = 0; active = 0; flip = 0; left = nullptr; right = nullptr; } Lazy(int l, int r) { L = l; R = r; flip = 0; if (L==R) { left = nullptr; right = nullptr; total_sum = storage[L]; if (a[L] == 1) active = total_sum; else active = 0; } else { int mid = (l+r)/2; left = new Lazy(l, mid); right = new Lazy(mid+1, r); total_sum = left->total_sum + right->total_sum; active = left->active + right->active; } } void update() { //assumption: My children could have just updated themselves, and so should I if (left!=nullptr) active = left->active + right->active; } void pancake_flip() { //assumption: this is updated, and I want to update myself active = total_sum - active; if (flip == 0) flip = 1; else flip = 0; } void push_down() { //assumption: this is updated, and I want to update my children if (flip == 1) { flip = 0; if (left != nullptr) { left->pancake_flip(); right->pancake_flip(); } } } void range_flip(int range_l, int range_r) { int intersect_l = max(range_l, L); int intersect_r = min(range_r, R); if ((intersect_l == L) and (intersect_r==R)) { pancake_flip(); push_down(); } else if (intersect_l <= intersect_r) { push_down(); left->range_flip(range_l, range_r); right->range_flip(range_l, range_r); update(); } } }; Lazy circ = Lazy(); struct factor{ public: ll mn; ll f2; ll f223; factor() { mn = 1; f2 = 0; f223 = 0; } factor(ll a, ll b, ll c) { mn = a; f2 = b; f223 = c; } factor(ll n) { //call this constructor for the degrees f2 = 0; f223 = 0; while ((n%2)==0) { n = n/2; f2++; } while ((n%223)==0) { n = n/223; f223++; } mn = n; } ll conv() { ll bb = pow(2ll, f2); ll cc = pow(223ll, f223); ll ans = (mn*bb)%MOD; ans = (ans*cc)%MOD; return ans; } }; factor multiply(factor x, factor y) { ll a = (x.mn * y.mn)%MOD; ll b = (x.f2 + y.f2); ll c = (x.f223 + y.f223); factor ans = factor(a, b, c); return ans; } factor divide(factor x, factor y) { ll d = inv(y.mn); factor mult = factor(d, 0ll-y.f2, 0ll-y.f223); return multiply(x, mult); } void init(int N, int M, std::vector<int> P, std::vector<int> A) { n = N; m = M; vector<ll> degrees(N, 0); for (int i=1; i<(N+M); i++) degrees[P[i]]++; vector<factor> orig(N); for (int i=0; i<N; i++) orig[i] = factor(degrees[i]); vector<factor> prods(N); prods[0] = orig[0]; for (int i=1; i<N; i++) prods[i] = multiply(prods[i-1], orig[i]); vector<factor> quots(N); quots[0] = divide(prods[N-1], orig[0]); for (int i=1; i<N; i++) quots[i] = divide(quots[P[i]], orig[i]); for (int i=N; i<(N+M); i++) { storage.push_back(quots[P[i]].conv()); } //NOTES: Fill in storage with the appropriate values! Initially it is empty. //MAKE SURE TO REDUCE ALL VALLUES MODULO MOD, THANK YOU! a = A; circ = Lazy(0, M-1); } int count_ways(int L, int R) { L -= n; R -= n; circ.range_flip(L, R); ll fa = circ.active%MOD; int ffa = fa; return ffa; }
#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...