Submission #937507

#TimeUsernameProblemLanguageResultExecution timeMemory
937507WhisperBitaro’s Party (JOI18_bitaro)C++17
100 / 100
1631 ms315596 KiB
#include <bits/stdc++.h>
 
using namespace std;
using ll = long long;
 
//#define int long long
#define FOR(i, a, b) for ( int i = a ; i <= b ; i++ )
#define FORD(i, a, b) for (int i = b; i >= a; i --)
#define REP(i, n) for (int i = 0; i < n; ++i)
#define REPD(i, n) for (int i = n - 1; i >= 0; --i)
#define Lg(x) 31 - __builtin_clz(x)
 
#define MASK(i) (1LL << (i))
#define BIT(x, i) (((x) >> (i)) & 1)
 
constexpr ll LINF = (1ll << 60);
constexpr int INF = (1ll << 30);
constexpr int MAX = 2e5 + 5;
constexpr int Mod = 1e9 + 7;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
 
void setupIO(){
    #define name "Whisper"
    //Phu Trong from Nguyen Tat Thanh High School for gifted student
    srand(time(NULL));
    cin.tie(nullptr)->sync_with_stdio(false); cout.tie(nullptr);
    //freopen(name".inp", "r", stdin);
    //freopen(name".out", "w", stdout);
    cout << fixed << setprecision(10);
}
 
template <class X, class Y>
    bool minimize(X &x, const Y &y){
        X eps = 1e-9;
        if (x > y + eps) {x = y; return 1;}
        return 0;
    }
 
template <class X, class Y>
    bool maximize(X &x, const Y &y){
        X eps = 1e-9;
        if (x + eps < y) {x = y; return 1;}
        return 0;
    }
int numNode, numQuery, numEdge;
 
vector<int> G[MAX];
vector<pair<int, int>> opt[MAX];
//opt(i) save the node has length x end at i
#define BLOCK 222
 
int dis[MAX], vis[MAX];
 
void Whisper(){
    cin >> numNode >> numEdge >> numQuery;
    for (int i = 1; i <= numEdge; ++i){
        int u, v; cin >> u >> v;
        //change the direction of DAG
        G[v].emplace_back(u);
    }
    // O(n * sqrt(n))
    // solving for case: c < BLOCK
    // because the number of unsatisfied node is smaller than BLOCK
    //=> the opt[u] size at most BLOCK is enough
    // we can proved that always exist a beavers that not busy in opt[u]
    for (int u = 1; u <= numNode; ++u){
        vector<int> current;
        for(int &v : G[u]){
            for (pair<int, int>& x : opt[v]){
                if (vis[x.second] == u){
                    maximize(dis[x.second], x.first + 1);
                }
                else {
                    vis[x.second] = u;
                    dis[x.second] = x.first + 1; current.push_back(x.second);
                }
            }
        }
        opt[u].emplace_back(0, u);
        for (int &v : current){
            opt[u].emplace_back(dis[v], v);
        }
 
        sort(opt[u].rbegin(), opt[u].rend());
        while ((int)opt[u].size() > BLOCK) opt[u].pop_back();
    }
    vector<int> busy(numNode + 1, 0);
    for (int t = 1; t <= numQuery; ++t){
        int x, c; cin >> x >> c;
        vector<int> rback;
        for(int i = 1; i <= c; ++i){
            int v; cin >> v;
            rback.push_back(v);
            busy[v] = 1;
        }
        if (c >= BLOCK){
            // using dp on DAG to solve this with total complexivity O(n)
            vector<int> dp(numNode + 1, -INF);
            for (int u = 1; u <= x; ++u){
                if (!busy[u]) maximize(dp[u], 0);
                for (int &v : G[u]){
                    maximize(dp[u], dp[v] + 1);
                }
            }
            maximize(dp[x], -1);
            cout << dp[x] << '\n';
        }
        else{
            int ans = -1;
            for (pair<int, int> v : opt[x]) if(!busy[v.second]){
                maximize(ans, v.first);
            }
            cout << ans << '\n';
        }
        for (auto&v : rback) busy[v] = 0;
    }
}
 
 
signed main(){
    setupIO();
    int Test = 1;
//    cin >> Test;
    for ( int i = 1 ; i <= Test ; i++ ){
        Whisper();
        if (i < Test) cout << '\n';
    }
}
 
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...