제출 #1347114

#제출 시각아이디문제언어결과실행 시간메모리
1347114SSKMFRailway (BOI17_railway)C++20
0 / 100
36 ms31232 KiB
#include <bits/stdc++.h>
using namespace std;

vector < pair <int , int> > adiacenta[100001];
int termen[100001] , adancime[100001] , inceput[100001] , sfarsit[100001] , tabel[18][200000] , sir[100001] , stiva[100001] , sursa[100001];
vector <int> necesar;

void Parcurgere (const int nod)
{
    adancime[nod] = adancime[sursa[nod]] + 1;
    tabel[0][++tabel[0][0]] = nod;
    inceput[nod] = tabel[0][0];

    for (auto& vecin : adiacenta[nod]) {
        if (vecin.first != sursa[nod])
        {
            sursa[vecin.first] = nod;
            Parcurgere(vecin.first);
            tabel[0][++tabel[0][0]] = nod;
        }
    }

    sfarsit[nod] = tabel[0][0];
}

int Combina (const int nod_1 , const int nod_2)
{
    return adancime[nod_1] < adancime[nod_2] ? nod_1 : nod_2;
}

int LCA (const int nod_1 , const int nod_2)
{
    const int stanga = min(inceput[nod_1] , inceput[nod_2]);
    const int dreapta = max(inceput[nod_1] , inceput[nod_2]);

    int exponent = 0;
    while ((1 << (exponent + 1)) <= dreapta - stanga + 1)
        { exponent++; }

    return Combina(tabel[exponent][stanga] , tabel[exponent][dreapta - (1 << exponent) + 1]);
}

void Check (const int nod , const int minim)
{
    for (auto& vecin : adiacenta[nod]) {
        if (vecin.first != sursa[nod])
        {
            Check(vecin.first , minim);
            if (termen[vecin.first] >= minim)
                { necesar.push_back(vecin.second); }

            termen[nod] += termen[vecin.first];
        }
    }
}

int main ()
{
    ios :: sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    int numar_noduri , numar_operatii , minim;
    cin >> numar_noduri >> numar_operatii >> minim;

    for (int indice = 1 ; indice < numar_noduri ; indice++)
    {
        int nod[2]; cin >> nod[0] >> nod[1];
        adiacenta[nod[0]].emplace_back(nod[1] , indice);
        adiacenta[nod[1]].emplace_back(nod[0] , indice);
    }

    Parcurgere(1);

    for (int exponent = 1 ; (1 << exponent) <= tabel[0][0] ; exponent++) {
        for (int indice = 1 ; indice + (1 << exponent) - 1 <= tabel[0][0] ; indice++)
            { tabel[exponent][indice] = Combina(tabel[exponent - 1][indice] , tabel[exponent - 1][indice + (1 << (exponent - 1))]); }
    }

    while (numar_operatii--)
    {
        int cantitate;
        cin >> cantitate;

        for (int indice = 1 ; indice <= cantitate ; indice++)
            { cin >> sir[indice]; }

        sort(sir + 1 , sir + cantitate + 1 , [] (int& optiune_1 , int& optiune_2) -> bool {
            return inceput[optiune_1] < inceput[optiune_2];
        });

        for (int indice = 1 ; indice <= cantitate ; indice++)
        {
            int anterior = 0;
            while (stiva[0] && !(inceput[stiva[stiva[0]]] < inceput[sir[indice]] && sfarsit[sir[indice]] < sfarsit[stiva[stiva[0]]]))
                { anterior = stiva[stiva[0]--]; }

            if (anterior != 0)
            {
                const int stramos = LCA(anterior , sir[indice]);

                termen[sir[indice]]++;
                termen[stramos]--;

                if (!stiva[0])
                {
                    termen[anterior]++;
                    termen[stramos]--;
                }
            }
            else
                if (stiva[0])
                {
                    termen[sir[indice]]++;
                    termen[stiva[stiva[0]]]--;
                }

            stiva[++stiva[0]] = sir[indice];
        }
    }

    Check(1 , minim);

    sort(necesar.begin() , necesar.end());

    cout << necesar.size() << '\n';

    for (auto& indice : necesar)
        { cout << indice << ' '; }

    return 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...