제출 #1177507

#제출 시각아이디문제언어결과실행 시간메모리
1177507ducanh0811Long Mansion (JOI17_long_mansion)C++20
0 / 100
550 ms22908 KiB
#include <bits/stdc++.h> #define fi first #define se second using namespace std; int n; #define MAXN 500005 int c[MAXN]; vector<int> a[MAXN]; int F[MAXN]; int G[MAXN]; int track[MAXN]; int pref[MAXN]; int suff[MAXN]; struct SMT{ int n; vector<pair<int,int>> st; SMT(int _n = 0) : n(_n) { st.assign((n << 2) + 5, make_pair(0, 0)); } void up(int id, int l, int r, int p, pair<int,int> val){ if (p < l || r < p) return; if (l == r) return st[id] = val, void(); int mid = (l + r) >> 1; up(id << 1, l, mid, p, val); up(id << 1 | 1, mid + 1, r, p, val); st[id].fi = max(st[id << 1].fi, st[id << 1 | 1].fi); st[id].se = min(st[id << 1].se, st[id << 1 | 1].se); } void up(int p, pair<int,int> val){ up(1, 1, n, p, val); } int getMAX(int id, int l, int r, int u, int v){ if (v < l || r < u) return 0; if (u <= l && r <= v) return st[id].fi; int mid = (l + r) >> 1; return max(getMAX(id<<1,l,mid,u,v), getMAX(id<<1|1,mid+1,r,u,v)); } int getMAX(int u, int v){ return getMAX(1, 1, n, u, v); } int getMIN(int id, int l, int r, int u, int v){ if (v < l || r < u) return 1e9; if (u <= l && r <= v) return st[id].se; int mid = (l + r) >> 1; return min(getMIN(id<<1,l,mid,u,v), getMIN(id<<1|1,mid+1,r,u,v)); } int getMIN(int u, int v){ return getMIN(1, 1, n, u, v); } }; void solve(){ cin >> n; for (int i = 1; i < n; ++i) cin >> c[i]; for (int i = 1; i <= n; ++i){ int m; cin >> m; for (int j = 1; j <= m; ++j){ int x; cin >> x; a[i].push_back(x); } } for (int i = 0; i <= n; ++i) track[i] = n + 1; for (int i = n; i >= 1; --i){ F[i] = track[c[i]]; for (int &x : a[i]) track[x] = i; } for (int i = 0; i <= n; ++i) track[i] = 0; for (int i = 1; i <= n; ++i){ G[i] = track[c[i-1]]; for (int &x : a[i]) track[x] = i; } SMT tree(n); for (int i = 1; i <= n; ++i) tree.up(i, make_pair(F[i], G[i])); for (int i = 1; i <= n; ++i) pref[i] = suff[i] = i; for (int i = 2; i <= n; ++i){ int lo = 1, hi = i - 1, pos = i; while (lo <= hi){ int mid = (lo + hi) >> 1; if (tree.getMAX(mid, i - 1) <= i){ pos = mid; hi = mid - 1; } else lo = mid + 1; } pref[i] = pos; } for (int i = n - 1; i >= 1; --i){ int lo = i + 1, hi = n, pos = i; while (lo <= hi){ int mid = (lo + hi) >> 1; if (tree.getMIN(i + 1, mid) >= i){ pos = mid; lo = mid + 1; } else hi = mid - 1; } suff[i] = pos; } int q; cin >> q; for (int i = 1; i <= q; ++i){ int x, y; cin >> x >> y; if (x < y){ if (pref[x] <= tree.getMIN(x + 1, y)){ cout << "YES" << '\n'; } else cout << "NO" << '\n'; } else { swap(x, y); if (suff[y] >= tree.getMAX(x, y - 1)){ cout << "YES" << '\n'; } else cout << "NO" << '\n'; } } } int32_t main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); solve(); 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...