Submission #1213855

#TimeUsernameProblemLanguageResultExecution timeMemory
1213855mdn2002Gift Exchange (JOI24_ho_t4)C++20
100 / 100
1782 ms99368 KiB
/*
Mayoeba Yabureru
*/
#pragma GCC optimize("O3,unroll-loops")
#include <bits/stdc++.h>
using namespace std;

const int N = 1e6;

int tree[N * 4], lazy[N * 4], mode = 0;

int merge (int x, int y) {
  if (mode == 0) return max(x, y);
  else return min(x, y);
}

int def () {
  if (mode == 0) return -1;
  else return N + 1;
}

void push (int node, int l, int r) {
  tree[node] = merge(tree[node], lazy[node]);
  if (l != r) {
    lazy[node * 2] = merge(lazy[node * 2], lazy[node]);
    lazy[node * 2 + 1] = merge(lazy[node * 2 + 1], lazy[node]);
  }
  lazy[node] = def();
}

void update (int x, int y, int val, int node = 1, int l = 0, int r = N) {
  push(node, l, r);
  if (y < l || r < x) return;
  if (x <= l && r <= y) {
    lazy[node] = val;
    push(node, l, r);
    return;
  }
  int mid = (l + r) / 2; 
  update(x, y, val, node * 2, l, mid);
  update(x, y, val, node * 2 + 1, mid + 1, r); 
  tree[node] = merge(tree[node * 2], tree[node * 2 + 1]);
}

int query (int x, int node = 1, int l = 0, int r = N) {
  push(node, l, r);
  if (x < l || r < x) return def();
  if (l == r) return tree[node];
  int mid = (l + r) / 2;
  return merge(query(x, node * 2, l, mid), query(x, node * 2 + 1, mid + 1, r));
}

int tree1[N * 4];

void update1 (int x, int val, int node = 1, int l = 0, int r = N) {
  if (x < l || r < x) return;
  if (l == r) {
    tree1[node] = merge(tree1[node], val);    
    return;
  }
  int mid = (l + r) / 2; 
  update1(x, val, node * 2, l, mid);
  update1(x, val, node * 2 + 1, mid + 1, r); 
  tree1[node] = merge(tree1[node * 2], tree1[node * 2 + 1]);
}

int query1 (int x, int y, int node = 1, int l = 0, int r = N) {
  if (y < l || r < x) return def();
  if (x <= l && r <= y) return tree1[node];

  int mid = (l + r) / 2;
  return merge(query1(x, y, node * 2, l, mid), query1(x, y, node * 2 + 1, mid + 1, r));
}

int tree2[N * 4];

void update2 (int x, int val, int node = 1, int l = 0, int r = N) {
  if (x < l || r < x) return;
  if (l == r) {
    tree2[node] = max(tree2[node], val);    
    return;
  }
  int mid = (l + r) / 2; 
  update2(x, val, node * 2, l, mid);
  update2(x, val, node * 2 + 1, mid + 1, r); 
  tree2[node] = max(tree2[node * 2], tree2[node * 2 + 1]);
}

int query2 (int x, int y, int node = 1, int l = 0, int r = N) {
  if (y < l || r < x) return -1;
  if (x <= l && r <= y) return tree2[node];

  int mid = (l + r) / 2;
  return max(query2(x, y, node * 2, l, mid), query2(x, y, node * 2 + 1, mid + 1, r));
}

void solve() {
  int n;
  cin >> n;

  vector a(n, 0), b = a, left(n, -1), right(n, n);
  for (int i = 0; i < n; i ++) cin >> a[i];
  for (int i = 0; i < n; i ++) cin >> b[i];

  for (int i = 0; i < 4 * N; i ++) {
    tree[i] = lazy[i] = tree1[i] = def();
  }

  for (int i = 0; i < n; i ++) {  
    left[i] = max(left[i], query(b[i]));
    left[i] = max(left[i], query1(b[i] + 1, a[i] - 1));
    update(b[i] + 1, a[i] - 1, i);
    update1(b[i], i);
  }

  mode = 1;
  for (int i = 0; i < 4 * N; i ++) {
    tree[i] = lazy[i] = tree1[i] = def();
  }

  for (int i = n - 1; i >= 0; i --) {  
    right[i] = min(right[i], query(b[i]));
    right[i] = min(right[i], query1(b[i] + 1, a[i] - 1));

    update(b[i] + 1, a[i] - 1, i);
    update1(b[i], i);
  }

  vector<vector<int>> events;
  for (int i = 0; i < n; i ++) events.push_back({left[i], i});

  int q;
  cin >> q;
  
  vector ans(q, 0);

  for (int i = 0; i < q; i ++) {
    int l, r;
    cin >> l >> r;
    l --, r--;
    events.push_back({l, -100000, r, i});
  }
  sort(events.begin(), events.end());

  for (auto v : events) {
    int l = v[0], r = v[1];
    if (r < 0) {
      r = v[2];
      if (r < query2(l, r)) ans[v[3]] = 0;
      else ans[v[3]] = 1;
    }
    else update2(r, right[r]);
  }

  for (int i = 0; i < q; i ++) {
    if (ans[i]) cout << "Yes\n";
    else cout << "No\n";
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  int T = 1;
  for (int I = 1; I <= T; I++) {
    solve();
  }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...