Official

D - Diversity of Scores Editorial by en_translator


One can manage the scores of the \(N\) players in a multiset and process the updates on the scores occurring at \(1,2,\dots,T\) seconds later.

There are a few data structures that can manage a multiset; in this problem, it is useful to use a data structure called an associative array (such as std::map or std::unordered_map in C++ or dictionary in Python). An associative array is somewhat an extension of an ordinary array; while an ordinary one uses consecutive integers like \(0,1,2,\dots\) as indices, an associative array allows us to use any values as indices. Starting from the initial state without indices, it can process addition and deletion of indices, modification of the value associated to an index, and retrieval of the size (the number of distinct indices) fast.

In this problem, it is sufficient to use the current scores of the players as indices, and maintain for each index \(x\) the number of players with score \(x\). Specifically, the algorithm would be like as follows:

  1. Prepare an associative array \(M\).
  2. Add an index \(0\) to \(M\), letting \(M[0]=N\).
  3. Prepare an array \(C=(C_1,C_2,\dots,C_N)\) that stores the scores of the players, initializing each element with \(0\).
  4. For each \(i=1,2,\dots, T\), do the following:
    1. Decrement \(M[C_{A_i}]\) by one.
    2. If \(M[C_{A_i}]\) has become \(0\), remove the index \(C_{A_i}\) from \(M\).
    3. Add \(B_i\) to \(C_{A_i}\).
    4. If \(M\) does not contain the index \(C_{A_i}\), insert it, letting \(M[C_{A_i}]=0\).
    5. Increment \(M[C_{A_i}]\) by \(1\).
    6. Print the current size (the number of elements) of \(M\).

The time complexity is \(O(N+T\log N)\) if you use std::map in C++, as in the following sample code.

Sample code (C++):

#include<bits/stdc++.h>

using namespace std;

using ll = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, t;
    cin >> n >> t;
    vector<ll> score(n);
    map<ll, int> mp;
    mp[0] = n;
    for (int i = 0; i < t; i++) {
        int a, b;
        cin >> a >> b;
        --a;
        if (--mp[score[a]] == 0) mp.erase(score[a]);
        score[a] += b;
        ++mp[score[a]];
        cout << mp.size() << '\n';
    }
}

posted:
last update: