// OBI 2023 - Fase 2 // Startup - Solução O(N log N + A log N) com manipulação de sets e vetores // Mateus Bezrutchka // #include #include #include using namespace std; const int MAXN = 100100; int n, a; int chefe[MAXN]; int salario[MAXN]; // guarda o negativo dos salarios, pro primeiro ser o maior multiset salarios_subordinados[MAXN]; int insatisfacao_atual; // mantém a resposta bool insatisfeito(int v) { if (salarios_subordinados[v].empty()) { return false; } int max_subord = -(*salarios_subordinados[v].begin()); return max_subord > salario[v]; } void calc_insatisfacao_inicial() { for (int i = 2; i <= n; i++) { salarios_subordinados[chefe[i]].insert(-salario[i]); } insatisfacao_atual = 0; for (int i = 1; i <= n; i++) { if (insatisfeito(i)) { insatisfacao_atual++; } } } // apenas duas pessoas podem ter sido afetadas pela // mudança atual: o próprio funcionário i, e o chefe dele void atualiza_salario(int i, int val) { int c = chefe[i]; // checa o status atual de insatisfação deles bool old_chefe_insatisfeito = insatisfeito(c); bool old_i_insatisfeito = insatisfeito(i); // atualiza salario if (i != 1) { salarios_subordinados[c].erase( salarios_subordinados[c].find(-salario[i]) ); salarios_subordinados[c].insert(-val); } salario[i] = val; // checa o novo status e atualiza a resposta de acordo bool new_chefe_insatisfeito = insatisfeito(c); bool new_i_insatisfeito = insatisfeito(i); if (old_i_insatisfeito != new_i_insatisfeito) { insatisfacao_atual += (new_i_insatisfeito ? 1 : -1); } if (i != 1 && old_chefe_insatisfeito != new_chefe_insatisfeito) { insatisfacao_atual += (new_chefe_insatisfeito ? 1 : -1); } } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d %d", &chefe[i], &salario[i]); } calc_insatisfacao_inicial(); printf("%d\n", insatisfacao_atual); scanf("%d", &a); while (a--) { int funcionario, novo_salario; scanf("%d %d", &funcionario, &novo_salario); atualiza_salario(funcionario, novo_salario); printf("%d\n", insatisfacao_atual); } return 0; }