This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |