제출 #835816

#제출 시각아이디문제언어결과실행 시간메모리
835816APROHACK디지털 회로 (IOI22_circuit)C++17
22 / 100
3019 ms49224 KiB
#include "circuit.h" #include <bits/stdc++.h> #define ll long long #define ff first #define ss second #define pb push_back using namespace std; int n, m; vector<int>child[200001]; bool state[200001]; ll encen[200001][2]; // encendido y apagado const ll MOD = 1000002022; ll past[2002][2002]; void generate(int node); int parent[200002]; bool casito = true; ll aporte[200002]; ll prefix[200002]; ll T[200002]; ll ans = 0; #define isCase4 false // seg tree ll sumaUno[200005*4]; ll sumaCero[200005*4]; bool lazy[200005*4]; ll aux1[200005]; ll aux0[200005]; int mid[200005*4]; void upd(int node); void cambiar(int node, int dd, int ht, int l, int r); void generate(int node, int dd, int ht){ mid[node] = (dd + ht)/2; if(dd == ht){ sumaUno[node] = aux1[dd]; sumaCero[node] = aux0[dd]; }else{ generate(node*2, dd, mid[node]); generate(node * 2 + 1, mid[node] + 1, ht ); upd(node); } } ll get1(int node){ if(lazy[node]){ return sumaCero[node]; }else return sumaUno[node]; } ll get0(int node){ if(lazy[node]){ return sumaUno[node]; }else return sumaCero[node]; } void upd(int node){ sumaUno[node] = (get1(node*2) + get1(node*2+1))%MOD; sumaCero[node] = (get0(node*2) + get0(node*2+1))%MOD; } void prop(int node, int dd, int ht){ if(lazy[node] ){ cout << "propagating from " << dd << " " << ht << endl; if(dd == ht)swap(sumaCero[node], sumaUno[node]); else{ cambiar(node*2, dd, mid[node], dd, mid[node]); cambiar(node*2+1, mid[node] + 1, ht, mid[node] + 1, ht); } } } void cambiar(int node, int dd, int ht, int l, int r){ if(dd == l and ht == r){ lazy[node] = !lazy[node]; //cout << "node " << dd << " " << ht << " exc " << lazy[node] << endl; } else{ prop(node, dd, ht); lazy[node] = 0; if(r <= mid[node])cambiar(node * 2, dd, mid[node], l, r); else if(mid[node] < l)cambiar(node*2+1, mid[node]+1, ht, l, r); else{ cambiar(node*2, dd, mid[node], l, mid[node]); cambiar(node*2+1, mid[node]+1, ht, mid[node] + 1, r); } upd(node); //cout << "node " << dd << " " << ht << " updated "; //cout << get1(node) << " " << get0(node) << endl; } } void precalc(int node){ T[node] = 1; if(node >= n)return ; for(int i = 0 ; i < child[node].size() ; i ++){ precalc(child[node][i]); T[node] = T[node] * T[child[node][i]] % MOD; } T[node] = T[node] * (ll)child[node].size() % MOD; } void calcPrefix(int node, ll acum){ if(node >= n){ aporte[node] = acum; //cout << "aporte de " << node << ": " << acum << endl; sumaUno[node] = 0; sumaCero[node] = 0; if(state[node])aux1[node] = aporte[node]; else aux0[node] = aporte[node]; return ; } int hijo1 = child[node][0]; int hijo2 = child[node][1]; calcPrefix(hijo1, (acum * T[hijo2]) % MOD); calcPrefix(hijo2, (acum * T[hijo1]) % MOD); } // void init(int N, int M, std::vector<int> P, std::vector<int> A) { n = N; m = M; if( m != n+1 )casito = false; for(int i = 0 ; i < n+m ; i ++){ if(P[i] != -1){ child[P[i]].pb(i); if(P[i] != (i-1)/2)casito = false; } parent[i] = P[i]; } int temp = m; while(temp != 1){ if(temp % 2 == 1)casito = false; temp /= 2; } //assert(casito); for(int i = N ; i <= N+M ; i ++){ state[i] = A[i-N]; } memset(past, -1, sizeof past); memset(lazy, false, sizeof lazy); generate(0); ans = encen[0][0]; if(isCase4 or ( casito and (n > 1000 or m > 1000) ) ){ precalc(0); calcPrefix(0, 1); generate(1, n, n+m-1); } } ll mem[2002][2002]; ll currentIt = -1 ; void newDp(){ currentIt++; } ll dp(int parent, ll i, int k){ if(k < 0)return 0; if(i == child[parent].size() and k > 0)return 0; else if(i == child[parent].size()) return 1; if(past[i][k] == currentIt)return mem[i][k]; past[i][k] = currentIt; return mem[i][k] = ((dp(parent, i+1, k-1) * encen[child[parent][i]][0] % MOD) + ((dp(parent, i+1, k) * encen[child[parent][i]][1])%MOD))%MOD; } void generate(int node){ if(node >= n){ if(state[node]){ encen[node][0] = 1; encen[node][1] = 0; }else{ encen[node][0] = 0; encen[node][1] = 1; } return ; } for(int i = 0 ; i < child[node].size() ; i ++){ generate(child[node][i]); } newDp(); ll enc = 0, inv = 0; for(ll i = 1 ; i <= child[node].size() ; i ++){ enc += dp(node, 0, i) * i % MOD; enc %= MOD; } ll allWays = 1; for(int i = 0 ; i < child[node].size() ; i ++){ allWays *= (encen[child[node][i]][0] + encen[child[node][i]][1])%MOD; allWays %= MOD; } allWays *= (ll)child[node].size(); allWays %= MOD; encen[node][0] = enc; encen[node][1] = ((allWays - enc) + MOD) % MOD; //cout << "for node " << node << " there are " << encen[node][0] << ", " << encen[node][1] << "\n"; } int count_ways(int L, int R) { for(int i = L ; i <= R ; i ++){ state[i] = !state[i]; } if(isCase4 or ( casito and (n > 1000 or m > 1000) ) ){ cambiar(1, n, n+m-1, L, R); return get1(1); } else generate(0); return encen[0][0]; }

컴파일 시 표준 에러 (stderr) 메시지

circuit.cpp: In function 'void precalc(int)':
circuit.cpp:94:20: 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 < child[node].size() ; i ++){
      |                  ~~^~~~~~~~~~~~~~~~~~~~
circuit.cpp: In function 'long long int dp(int, long long int, int)':
circuit.cpp:158:7: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  158 |  if(i == child[parent].size() and k > 0)return 0;
      |     ~~^~~~~~~~~~~~~~~~~~~~~~~
circuit.cpp:159:12: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  159 |  else if(i == child[parent].size()) return 1;
      |          ~~^~~~~~~~~~~~~~~~~~~~~~~
circuit.cpp: In function 'void generate(int)':
circuit.cpp:177:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  177 |  for(int i = 0 ; i < child[node].size() ; i ++){
      |                  ~~^~~~~~~~~~~~~~~~~~~~
circuit.cpp:182:19: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  182 |  for(ll i = 1 ; i <= child[node].size() ; i ++){
      |                 ~~^~~~~~~~~~~~~~~~~~~~~
circuit.cpp:187:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  187 |  for(int i = 0 ; i < child[node].size() ; i ++){
      |                  ~~^~~~~~~~~~~~~~~~~~~~
circuit.cpp:181:14: warning: unused variable 'inv' [-Wunused-variable]
  181 |  ll enc = 0, inv = 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...