#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll long long
#define ld long double
#define ull unsigned long long
#define ff first
#define ss second
#define pii pair<int,int>
#define pll pair<long long, long long>
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define siz(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace __gnu_pbds;
using namespace std;
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());}
//ll los(ll a, ll b) {return a + (mt() % (b-a+1));}
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
const ll MOD = 1e9+7;
int rep_[500'002];
int fint(int v)
{
if(rep_[v] == v) return v;
rep_[v] = fint(rep_[v]);
return rep_[v];
}
void onion(int a, int b)
{
a = fint(a);
b = fint(b);
rep_[a] = b;
}
int key[500'002];
vi keys[500'002];
pii ans[500'002];
int prev_[500'002];
int Lp[500'002];
int Rp[500'002];
int odw[500'002];
int n;
pii dfs(int v)
{
v = fint(v);
if(odw[v]) return ans[v];
odw[v] = 2;
int l = v;
int r = v;
while(true)
{
ans[fint(v)] = {l,r};
//cout << v << " " << l << " " << r << " seg\n";
bool was = 0;
if(l != 1 && Rp[l-1] <= r)
{
pii new_seg = dfs(l-1);
if(new_seg.ss >= v)
{
onion(v,l-1);
ans[v] = new_seg;
return ans[v];
}
l = min(l,new_seg.ff);
r = max(r,new_seg.ss);
was = 1;
}
ans[fint(v)] = {l,r};
//cout << v << " " << l << " " << r << " seg\n";
if(r != n && Lp[r] >= l)
{
pii new_seg = dfs(r+1);
if(new_seg.ff <= v)
{
onion(v,r+1);
ans[v] = new_seg;
return ans[v];
}
l = min(l,new_seg.ff);
r = max(r,new_seg.ss);
was = 1;
}
ans[fint(v)] = {l,r};
//cout << v << " " << l << " " << r << " seg\n";
if(!was) break;
}
ans[fint(v)] = {l,r};
odw[v] = 1;
return {l,r};
}
int main()
{
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//random_start();
cin >> n;
rep2(i,1,n) rep_[i] = i;
rep_[n+1] = n+1;
rep2(i,1,n-1) cin >> key[i];
key[n] = 0;
rep2(i,1,n)
{
int x;
cin >> x;
rep(j,x)
{
int z;
cin >> z;
keys[i].pb(z);
}
}
rep2(i,1,n-1)
{
forall(it,keys[i]) prev_[it] = i;
Lp[i] = prev_[key[i]];
}
rep2(i,1,n) prev_[i] = n+1;
for(int i = n; i >= 1; i--)
{
Rp[i] = prev_[key[i]];
forall(it,keys[i]) prev_[it] = i;
}
rep2(i,1,n)
{
if(odw[i] == 0)
{
dfs(i);
}
}
int q;
cin >> q;
rep(qq,q)
{
int a,b;
cin >> a >> b;
if(ans[a].ff <= b && ans[a].ss >= b) cout << "YES\n";
else cout << "NO\n";
}
}
# | 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... |