Submission #854332

#TimeUsernameProblemLanguageResultExecution timeMemory
854332DAleksaLong Mansion (JOI17_long_mansion)C++17
100 / 100
1442 ms132656 KiB
#include <bits/stdc++.h> using namespace std; const int N = 5e5 + 10, LOG = 20; int n, q; int need[N]; int c[N]; vector<int> keys[N]; int L[N], R[N]; int prv[N], nxt[N]; int lst[N]; int st_prv[N][LOG], st_nxt[N][LOG]; int get_prv(int l, int r) { if(l > r) return INT_MAX; int len = r - l + 1; int bit = 31 - __builtin_clz(len); return min(st_prv[l][bit], st_prv[r - (1 << bit) + 1][bit]); } int get_nxt(int l, int r) { if(l > r) return 0; int len = r - l + 1; int bit = 31 - __builtin_clz(len); return max(st_nxt[l][bit], st_nxt[r - (1 << bit) + 1][bit]); } int find_left(int start, int target) { int l = 1, r = start; int ans = r; while(l <= r) { int mid = (l + r) / 2; if(get_nxt(mid, start - 1) <= target) { ans = mid; r = mid - 1; } else l = mid + 1; } return ans; } int find_right(int target, int start) { int l = start, r = n; int ans = l; while(l <= r) { int mid = (l + r) / 2; if(get_prv(start, mid - 1) >= target) { ans = mid; l = mid + 1; } else r = mid - 1; } return ans; } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cin >> n; for(int i = 1; i < n; i++) cin >> need[i]; for(int i = 1; i <= n; i++) { cin >> c[i]; keys[i].resize(c[i]); for(int j = 0; j < c[i]; j++) cin >> keys[i][j]; } for(int i = 1; i < n; i++) { for(int j : keys[i]) lst[j] = i; prv[i] = lst[need[i]]; } for(int i = 0; i < N; i++) lst[i] = n + 1; for(int i = n; i > 1; i--) { for(int j : keys[i]) lst[j] = i; nxt[i - 1] = lst[need[i - 1]]; } for(int i = 1; i < n; i++) { st_prv[i][0] = prv[i]; st_nxt[i][0] = nxt[i]; } for(int j = 1; j < LOG; j++) { for(int i = 1; i + (1 << (j - 1)) < n; i++) { st_prv[i][j] = min(st_prv[i][j - 1], st_prv[i + (1 << (j - 1))][j - 1]); st_nxt[i][j] = max(st_nxt[i][j - 1], st_nxt[i + (1 << (j - 1))][j - 1]); } } L[1] = 1; R[1] = find_right(1, 1); for(int i = 2; i <= n; i++) { L[i] = R[i] = i; if(R[i - 1] == i - 1) { R[i] = find_right(i, i); while(true) { int temp = find_left(L[i], R[i]); if(temp == L[i]) break; L[i] = temp; temp = find_right(L[i], R[i]); if(temp == R[i]) break; R[i] = temp; } } else { R[i] = find_right(i, i); L[i] = find_left(i, R[i]); if(L[i] < i) { L[i] = L[i - 1]; R[i] = R[i - 1]; } } } int q; cin >> q; while(q--) { int l, r; cin >> l >> r; cout << ((L[l] <= r && r <= R[l]) ? "YES\n" : "NO\n"); } 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...