Submission details
Task:Yhdistelmät
Sender:sharph2
Submission time:2025-11-29 11:34:44 +0200
Language:C++ (C++17)
Status:COMPILE ERROR

Compiler report

input/code.cpp: In function 'std::pair<int, Maski> hae(Maski, Maski)':
input/code.cpp:86:9: error: 'tie' was not declared in this scope
   86 |         tie(tulosTuotto, tulosEsineet) = hae(loputEsineet, loputYhdistelmat);
      |         ^~~
input/code.cpp:5:1: note: 'std::tie' is defined in header '<tuple>'; did you forget to '#include <tuple>'?
    4 | #include <vector>
  +++ |+#include <tuple>
    5 |

Code

#include <climits>
#include <cstdint>
#include <iostream>
#include <vector>

using namespace std;

struct Maski {
    uint64_t a = 0;
    uint64_t b = 0;

    void lisaa(int x) {
        if(x < 64) {
            a |= uint64_t{1} << x;
        } else {
            b |= uint64_t{1} << (x - 64);
        }
    }
    void poista(int x) {
        if(x < 64) {
            a &= ~(uint64_t{1} << x);
        } else {
            b &= ~(uint64_t{1} << (x - 64));
        }
    }
    bool hae(int x) const {
        if(x < 64) {
            return (a & (uint64_t{1} << x)) != 0;
        } else {
            return (b & (uint64_t{1} << (x - 64))) != 0;
        }
    }

    int lkm() const {
        return __builtin_popcountll(a) + __builtin_popcountll(b);
    }

    bool operator==(const Maski& m) const {
        return a == m.a && b == m.b;
    }

    Maski operator&(const Maski& m) const {
        return {a & m.a, b & m.b};
    }
};

int n, m;
vector<int> esineenHinta;
vector<int> yhdistelmanPalkkio;
vector<Maski> yhdistelmanEsineet;
vector<Maski> esineenYhdistelmat;

pair<int, Maski> hae(Maski esineet, Maski yhdistelmat) {
    int suosituinEsineIdx = -1;
    int suosituinEsineYhdistelmaLkm = 0;
    for(int esineIdx = 0; esineIdx < n; ++esineIdx) {
        if(esineet.hae(esineIdx)) {
            int yhdistelmaLkm = (esineenYhdistelmat[esineIdx] & yhdistelmat).lkm();
            if(yhdistelmaLkm > suosituinEsineYhdistelmaLkm) {
                suosituinEsineIdx = esineIdx;
                suosituinEsineYhdistelmaLkm = yhdistelmaLkm;
            }
        }
    }

    if(suosituinEsineIdx == -1) {
        return {0, {}};
    }

    Maski loputEsineet = esineet;
    loputEsineet.poista(suosituinEsineIdx);

    int tulosTuotto = 0;
    Maski tulosEsineet;

    // Valitaan esine suosituinEsineIdx mukaan
    {
        int palkkiot = 0;
        Maski loputYhdistelmat = yhdistelmat;
        for(int yhdistelmaIdx = 0; yhdistelmaIdx < m; ++yhdistelmaIdx) {
            if(yhdistelmat.hae(yhdistelmaIdx) && (yhdistelmanEsineet[yhdistelmaIdx] & loputEsineet) == Maski()) {
                loputYhdistelmat.poista(yhdistelmaIdx);
                palkkiot += yhdistelmanPalkkio[yhdistelmaIdx];
            }
        }
        tie(tulosTuotto, tulosEsineet) = hae(loputEsineet, loputYhdistelmat);
        tulosTuotto += palkkiot - esineenHinta[suosituinEsineIdx];
        tulosEsineet.lisaa(suosituinEsineIdx);
    }

    // Jätetään esine suosituinEsineIdx valitsematta
    {
        Maski loputYhdistelmat = yhdistelmat;
        for(int yhdistelmaIdx = 0; yhdistelmaIdx < m; ++yhdistelmaIdx) {
            if(yhdistelmat.hae(yhdistelmaIdx) && yhdistelmanEsineet[yhdistelmaIdx].hae(suosituinEsineIdx)) {
                loputYhdistelmat.poista(yhdistelmaIdx);
            }
        }
        auto [tuotto, esineet] = hae(loputEsineet, loputYhdistelmat);
        if(tuotto > tulosTuotto) {
            tulosTuotto = tuotto;
            tulosEsineet = esineet;
        }
    }

    return {tulosTuotto, tulosEsineet};
}

int main() {
    cin.sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> m;

    esineenHinta.resize(n);
    esineenYhdistelmat.resize(n);
    for(int& x : esineenHinta) {
        cin >> x;
    }

    yhdistelmanPalkkio.resize(m);
    yhdistelmanEsineet.resize(m);
    for(int yhdistelmaIdx = 0; yhdistelmaIdx < m; ++yhdistelmaIdx) {
        int k;
        cin >> k >> yhdistelmanPalkkio[yhdistelmaIdx];
        for(int j = 0; j < k; ++j) {
            int esineIdx;
            cin >> esineIdx;
            --esineIdx;
            yhdistelmanEsineet[yhdistelmaIdx].lisaa(esineIdx);
            esineenYhdistelmat[esineIdx].lisaa(yhdistelmaIdx);
        }
    }

    Maski kaikkiEsineet;
    for(int esineIdx = 0; esineIdx < n; ++esineIdx) {
        kaikkiEsineet.lisaa(esineIdx);
    }
    Maski kaikkiYhdistelmat;
    for(int yhdistelmaIdx = 0; yhdistelmaIdx < m; ++yhdistelmaIdx) {
        kaikkiYhdistelmat.lisaa(yhdistelmaIdx);
    }

    auto [tuotto, esineet] = hae(kaikkiEsineet, kaikkiYhdistelmat);

    cout << tuotto << "\n";

    int lkm = 0;
    for(int i = 0; i < n; ++i) {
        if(esineet.hae(i)) {
            ++lkm;
        }
    }
    cout << lkm << "\n";

    for(int i = 0; i < n; ++i) {
        if(esineet.hae(i)) {
            cout << i + 1 << " ";
        }
    }
    cout << "\n";

    return 0;
}