Official

E - Dislike Foods Editorial by en_translator


First, let us naively follow the procedure in the problem statement: for each \(i=1,2,\ldots,N\), count the number of dishes in the AtCoder Restaurant that he can eat after overcoming ingredient \(B_i\). Maintain whether he dislikes each ingredient in an array, and for each \(i=1,2,\ldots ,N\) in order, inspect \(M\) dishes and check all the ingredient included to check if it is edible for him. However, this approach costs \(\mathrm{\Theta }(N(\sum K_i +M))\) time at worst, making it difficult to solve it under the constraints of the problem.

What is the bottleneck of this solution? Scanning all the dishes for each day is. Instead of inspecting them every day, we need to care about the difference from the previous day, and inspect only the dishes containing the ingredient overcome on that day. This is because, when he overcomes ingredient \(B_i\) on day \(i\), a dish may become newly edible only if it contains ingredient \(B_i\). On day \(i\), one can check if a dish containing ingredient \(B_i\) becomes edible by overcoming ingredient \(i\) by managing the number of ingredient he dislikes for each dish and updating the count accordingly.

Therefore, the answer can be found by iterating the disliked ingredient from day \(1\) in order, while updating the number of disliked ingredients contained in each dish, and once the count becomes zero, increment the number of edible dishes by one. Specifically, when he overcomes an ingredient, we can decrement by one the number of disliked ingredient for each dish containing that ingredient. One can manage the list of dishes containing an ingredient in a two-dimensional array.

The sum of the number of ingredients contained in the dishes equal the sum of the number of dishes that contain each ingredient, which equals \(\sum K_i\). Therefore, the values can be updated in a total of \(\mathrm{O}(N+\sum K_i)\) time.

Therefore, the problem can be solved in \(\mathrm{O}(N+M+\sum K_i)\) time.

Sample code (C++):

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> a(m);
    vector<vector<int>> idx(n);
    vector<int> cnt(m);
    for (int i = 0; i < m; ++i) {
        int k;
        cin >> k;
        cnt[i] = k;
        a[i].resize(k);
        for (auto &e : a[i]) {
            cin >> e, e--;
            idx[e].push_back(i);
        }
    }
    int ans = 0;
    for (int i = 0; i < n; ++i) {
        int b;
        cin >> b;
        b--;
        for (auto id : idx[b]) {
            cnt[id]--;
            if (cnt[id] == 0)
                ans++;
        }
        cout << ans << endl;
    }
}

posted:
last update: