Submission #51857

#TimeUsernameProblemLanguageResultExecution timeMemory
51857shoemakerjoBitaro’s Party (JOI18_bitaro)C++14
100 / 100
1820 ms242352 KiB
#include <bits/stdc++.h> using namespace std; #define maxn 100010 #define endl '\n' const int block = 300; const int inf = 1234567890; int bestval[maxn][block]; //all 0's is good int bestdist[maxn][block]; //starts at all 0's which is good int ndist[block]; int nval[block]; int bd[maxn]; //used for things that are greater than square root n int bv[maxn]; bool cseen[maxn]; //used during the merge thing bool illegal[maxn]; //used for queries greater than maxn int N, M, Q; vector<vector<int>> adj(maxn); void merge(int x, int y) { // cout << "merging: " << x << " into " << y << endl; //merge everything from y into x (going to y will increase distance by 1) int ind = -1; int p1 = 0; int p2 = 0; while (++ind < block) { //run a merge-sort like algorithm // cout << ind << " - " << block << endl; cseen[0] = false; while (cseen[bestval[x][p1]]) ++p1; while (cseen[bestval[y][p2]]) ++p2; if (bestdist[x][p1] > bestdist[y][p2]+1) { ndist[ind] = bestdist[x][p1]; nval[ind] = bestval[x][p1]; p1++; cseen[nval[ind]] = true; } else { ndist[ind] = bestdist[y][p2]+1; nval[ind] = bestval[y][p2]; p2++; cseen[nval[ind]] = true; } } for (int i = 0; i < block; i++) { bestval[x][i] = nval[i]; bestdist[x][i] = ndist[i]; cseen[nval[i]] = false; //unmark it for the next iteration } } void recalculate() { for (int i = 1; i <= N; i++) { bd[i] = 0; if (!illegal[i]) { bv[i] = i; } else { bv[i] = 0; bd[i] = -inf; } for (int val : adj[i]) { if (bd[val] + 1 > bd[i]) { bd[i] = bd[val]+1; bv[i] = bv[val]; //don't think i actually need this but maybe } } } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> N >> M >> Q; int ti; //party location in the query int yi; //used for queries int s, e; //used for edges for (int i = 0; i < M; i++) { cin >> s >> e; //reverse edges here adj[e].push_back(s); } //process from back to front for (int i = 1; i <= N; i++) { // cout << "at: " << i << endl; //want what can get to this (or what this gets to in reversed graph) fill(bestdist[i], bestdist[i]+block, -inf); //calculate everything for this bestval[i][0] = i; //store myself bestdist[i][0] = 0; for (int val : adj[i]) { merge(i, val); } // cout << "best dist for " << i << ": " << bestdist[i][0] << endl; } int cur; while (Q--) { // cout << "here: " << Q << endl; cin >> ti >> yi; vector<int> cl; //current illegal for (int i = 0; i < yi; i++) { cin >> cur; cl.push_back(cur); illegal[cur] = true; } //do processing if (yi < block) { //do first thing int ind = 0; while (illegal[bestval[ti][ind]]) { // cout << ind << ": " << bestval[ti][ind] << endl; ind++; } // cout << ind << ": " << bestval[ti][ind] << endl; if (bestval[ti][ind] != 0 && bestdist[ti][ind] >= 0) { cout << bestdist[ti][ind] << endl; } else cout << -1 << endl; } else { recalculate(); if (bv[ti] != 0 && bd[ti] >= 0) { cout << bd[ti] << endl; //we just want the distance, not the index } else cout << -1 << endl; } //mark the things as ok again for (int i = 0; i < yi; i++) { illegal[cl[i]] = false; } } cout.flush(); cin >> N; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...