Submission #1096154

#TimeUsernameProblemLanguageResultExecution timeMemory
1096154Zero_OPBitaro’s Party (JOI18_bitaro)C++14
14 / 100
214 ms63360 KiB
#include "bits/stdc++.h" using namespace std; #define sz(v) (int)v.size() #define all(v) begin(v), end(v) #define compact(v) v.erase(unique(all(v)), end(v)) const int MAX = 1e5 + 5; int SQRT = 350; int n, m, q, dp[MAX], f[MAX]; vector<int> adj[MAX], rev[MAX]; bool bad[MAX], vis[MAX]; //only take B nodes vector<pair<int, int>> S[MAX], tmpS; bool better(int u, int v){ return (dp[u] == dp[v] ? u < v : dp[u] > dp[v]); } void merge(vector<pair<int, int>>& A, vector<pair<int, int>>& B){ tmpS.clear(); int i = 0, j = 0; while(i < sz(A) || j < sz(B)){ if(i == sz(A)) tmpS.push_back(B[j++]); else if(j == sz(B)) tmpS.push_back(A[i++]); else if(A[i] < B[j]) tmpS.push_back(A[i++]); else tmpS.push_back(B[j++]); } A = tmpS; } void insert(vector<pair<int, int>>& A, vector<pair<int, int>>& B){ //define A is larger set merge(A, B); compact(A); while(sz(A) > SQRT + 1) A.pop_back(); } int dfsDP(int u){ if(vis[u]) return dp[u]; vis[u] = true; for(int v : adj[u]){ dp[u] = max(dp[u], dfsDP(v) + 1); } return dp[u]; } queue<int> qu; void bfsAdj(int s){ vis[s] = true; qu.push(s); while(!qu.empty()){ int u = qu.front(); qu.pop(); for(int v : adj[u]){ insert(S[v], S[u]); if(!vis[v]){ vis[v] = true; qu.push(v); } } } } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> m >> q; for(int i = 0; i < m; ++i){ int u, v; cin >> u >> v; adj[u].push_back(v); rev[v].push_back(u); } for(int i = n; i >= 1; --i){ if(!vis[i]){ dfsDP(i); } } SQRT = sqrt(n); for(int i = 1; i <= n; ++i){ S[i].push_back({-dp[i], i}); } fill(vis + 1, vis + 1 + n, false); for(int i = 1; i <= n; ++i){ if(!vis[i]){ bfsAdj(i); } } // for(int i = 1; i <= n; ++i){ // cout << i << " : "; // for(auto j : S[i]) cout << j.first << ' ' << j.second << '\n'; cout << '\n'; // } while(q--){ int t, y; cin >> t >> y; vector<int> nodes(y); for(int i = 0; i < y; ++i) cin >> nodes[i]; for(int u : nodes) bad[u] = true; if(y > SQRT){ // cout << "heavy\n"; fill(f + 1, f + 1 + n, -1e9); f[t] = 0; for(int i = t; i > 0; --i){ for(int j : rev[i]){ f[j] = max(f[j], f[i] + 1); } } int ans = -1; for(int i = t; i > 0; --i){ if(!bad[i]) ans = max(ans, f[i]); } cout << ans << '\n'; } else{ // cout << "light\n"; int ans = -1; for(auto u : S[t]){ if(!bad[u.second]){ ans = -u.first; break; } } if(ans == -1){ cout << ans << '\n'; } else{ ans -= dp[t]; cout << ans << '\n'; } } for(int u : nodes) bad[u] = false; } return 0; } /* test 1 : 5 6 3 1 2 2 4 3 4 1 3 3 5 4 5 4 1 1 5 2 2 3 2 3 1 4 5 test 2 : 12 17 10 1 2 2 3 3 4 1 5 2 6 3 7 4 8 5 6 6 7 7 8 5 9 6 10 7 11 8 12 9 10 10 11 11 12 6 3 1 7 12 3 7 1 2 3 4 5 6 7 11 3 1 3 5 9 2 1 9 8 4 1 2 3 4 1 1 1 12 0 10 3 1 6 10 11 8 2 3 5 6 7 9 10 11 8 7 2 3 4 5 6 7 8 test 3 : 12 17 1 1 2 2 3 3 4 1 5 2 6 3 7 4 8 5 6 6 7 7 8 5 9 6 10 7 11 8 12 9 10 10 11 11 12 12 0 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...