제출 #1125000

#제출 시각아이디문제언어결과실행 시간메모리
1125000acoatoitgsBitaro’s Party (JOI18_bitaro)C++17
14 / 100
137 ms21076 KiB
#include <bits/extc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define pb push_back
#define m_pi 2 * acos(0.0)
#define all(a) (a).begin(), (a).end()
#define LL_INF 0x3f3f3f3f3f3f3f3f
#define INF 0x3f3f3f3f
void solve();

constexpr bool isTc = 0;
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);

    if (isTc)
    {
        int T;
        cin >> T;
        while (T--)
        {
            solve();
        }
    }
    else
        solve();
    return 0;
}

/*######################################*/

int SQRT;

vector<vector<int>> adj, radj;
int N, M, Q;

void i_merge(vector<pair<int,int>> &S, vector<pair<int,int>> &T)
{   
    for(auto &i : S) i.first++;
    vector<pair<int,int>> nS;
    
    int i = 0, l = 0;
    gp_hash_table<int, bool> used;

    while(i < S.size() && l < T.size() && nS.size() < SQRT)
    {
        if(S[i].first > T[l].first)
        {
            if(!used[S[i].second])
            {
                nS.push_back(S[i]);
            }
            
            used[S[i].second] = 1;
            i++;
        }
        else
        {
            if(!used[T[l].second])
            {
                nS.push_back(T[l]);
            }
            used[T[l].second] = 1;
            l++;
        }

        if(nS.size() >= SQRT)
        {
            if(nS.size() > SQRT) nS.resize(SQRT);
            for(auto &i : S) i.first--;

            T = nS;
            return;
        }

        if(i == S.size())
        {
            while(l < T.size() && nS.size() < SQRT)
            {
                if(!used[T[l].second])
                {
                    nS.push_back(T[l]);
                }
                used[T[l].second] = 1;
                l++;
            }
        }
        else
        {
            while(i < S.size() && nS.size() < SQRT)
            {
                if(!used[S[i].second])
                {
                    nS.push_back(S[i]);
                }
                
                used[S[i].second] = 1;
                i++;
            }
        }   
        

        if(nS.size() > SQRT) nS.resize(SQRT);
        for(auto &i : S) i.first--;

        T = nS;
    }
}
void precompute(vector<vector<pair<int,int>>> &pre)
{
    for(int i = 1; i <= N; i++)
    {
        pre[i].push_back({0, i});
    }

    for(int i = 1; i <= N; i++)
    {
        for(auto edge : adj[i])
        {
            i_merge(pre[i], pre[edge]);
        }
    }
}
vector<int> memo;
int dp(int node, bitset<100005> &bs)
{   
    if(memo[node] != -1) return memo[node];

    int best = 0;    
    for(auto i : radj[node])
    {   
        int d = dp(i, bs);
        if(d != 0 || !bs[i])
            best = max(best, d+1);
    }

    return memo[node] = best;
}

void solve()
{
    cin >> N >> M >> Q;
    memo.resize(N+1, -1);
    adj.resize(N+1);
    radj.resize(N+1);
    for(int i = 0; i < M; i++)
    {
        int a,b;
        cin >> a >> b;
        adj[a].emplace_back(b);
        radj[b].emplace_back(a);
    }
    SQRT = sqrt(N);
    
    vector<vector<pair<int,int>>> pre(N+1);
    precompute(pre);

    // for(int i = 1; i <= N; i++)
    // {
    //     cout << i << " : ";
    //     for(auto k : pre[i]) cout << "{" << k.first << ", " << k.second << "} ";
    //     cout << "\n";
    // }

    bitset<100005> rm;
    while(Q--)
    {   
        int T, Y, x;
        vector<int> m;
        cin >> T >> Y;
        m.reserve(Y);
        
        for(int i = 0; i < Y; i++)
        {
            cin >> x;
            rm[x] = 1;
            m.push_back(x);
        }

        int ans = 0;
        if(Y >= SQRT)
        {   
            // cout << "DPING\n";
            fill(all(memo), -1);
            ans = dp(T, rm);
        }
        else
        {
            for(auto i : pre[T])
            {
                if(rm[i.second]) continue;

                ans = i.first;
                break;
            }
        }

        cout << (ans == 0 && rm[T] ? -1 : ans) << "\n";
        for(auto i : m) rm[i] = 0;
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...