Submission #1327105

#TimeUsernameProblemLanguageResultExecution timeMemory
1327105husseinjuandaLong Mansion (JOI17_long_mansion)C++20
100 / 100
2319 ms61288 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

vector<int> t;
vector<int> lf;

void build(int i, int l, int r){
    if(l == r){
        t[i] = lf[l];
        return;
    }
    int mid = (l + r)/2;
    build(i*2, l, mid);
    build(i*2+1, mid+1, r);
    t[i] = min(t[i*2], t[i*2+1]);
}

int query(int i, int l, int r, int l1, int r1){
    if(l1 > r || l > r1){
        return 1e9;
    }
    if(l1 <= l && r1 >= r){
        return t[i];
    }
    int mid = (l + r)/2;
    return min(query(i*2, l, mid, l1, r1), query(i*2+1, mid+1, r, l1, r1));
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n; cin >> n;
    t.resize(n*4);
    vector<int> c(n-1);
    for(int i = 0; i < n-1; i++){
        cin >> c[i];
    }
    vector<vector<int>> key(n+1);
    vector<vector<int>> x(n);
    for(int i = 0; i < n; i++){
        int c; cin >> c;
        x[i].resize(c);
        for(int y = 0; y < c; y++){
            cin >> x[i][y];
            key[x[i][y]].push_back(i);
        }
    } 
    lf.resize(n, -1);
    for(int i = 0; i < n-1; i++){
        auto it = lower_bound(key[c[i]].begin(), key[c[i]].end(), i+1);
        if(it == key[c[i]].begin()){
            continue;
        }
        it--;
        lf[i+1] = *it; 
    }
    vector<int> r(n, -1);
    for(int i = 0; i < n-1; i++){
        auto it = lower_bound(key[c[i]].begin(), key[c[i]].end(), i+1);
        if(it == key[c[i]].end()){
            continue;
        }
        r[i] = *it;
    }
    build(1, 0, n-1);
    vector<pair<int, int>> seg(n);
    for(int i = 0; i < n; i++){
        seg[i] = {i, i};
    }
    for(int i = 0; i < n; i++){
        while(true){
            int low = seg[i].second;
            int top = n-1;
            int ns = 0;
            while(low <= top){
                int mid = (low + top)/2;
                int j = query(1, 0, n-1, seg[i].second+1, mid);
                if(j >= seg[i].first){
                    low = mid+1;
                    ns = mid;
                }else{
                    top = mid-1;
                }
            }
            seg[i].second = ns;
            if(seg[i].first == 0){
                break;
            }
            if(seg[i].first <= r[seg[i].first-1] && seg[i].second >= r[seg[i].first-1]){
                seg[i].first--;
            }else{
                break;
            }
            seg[i].first = seg[seg[i].first].first;
        }
    }
    int q; cin >> q;
    while(q--){
        int a, b; cin >> a >> b;
        a--;
        b--;
        if(seg[a].first <= b && seg[a].second >= b){
            cout << "YES" << "\n";
        }else{
            cout << "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...