Cod sursa(job #1992884)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 21 iunie 2017 18:17:05
Problema Pq Scor 100
Compilator cpp Status done
Runda Arhiva ICPC Marime 2.85 kb
#include <stdio.h>
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pdd pair<ld, ld>
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second

struct Query {
  int x, y, i;

  Query(int x_, int y_, int i_) : x(x_), y(y_), i(i_) {}

  bool operator < (const Query& other) const {
    return y < other.y;
  }
};

template<typename T>
class SegmentTree {
 public:
  explicit SegmentTree(const int size) : size_(size) {
    segment_.resize(4 * size + 5);
    fill(all(segment_), -1);
  }

  void Update(const int position, const T value) {
    return Update(1, 1, size_, position, value);
  }

  T Query(const int left, const int right) const {
    return Query(1, 1, size_, left, right);
  }

 private:
  void Update(const int node, const int left, const int right,
              const int position, const T value) {
    if (left == right) {
      segment_[node] = value;
      return;
    }

    int middle = (left + right) / 2;
    int left_son = 2 * node;
    int right_son = 2 * node + 1;

    if (position <= middle) {
      Update(left_son, left, middle, position, value);
    } else {
      Update(right_son, middle + 1, right, position, value);
    }

    Merge(node);
  }

  T Query(const int node, const int left, const int right, const int a,
          const int b) const {
    if (left >= a && right <= b) {
      return segment_[node];
    }

    int middle = (left + right) / 2;
    int left_son = 2 * node;
    int right_son = 2 * node + 1;

    T x = -1;
    T y = -1;

    if (a <= middle) {
      x = Query(left_son, left, middle, a, b);
    }
    if (b > middle) {
      y = Query(right_son, middle + 1, right, a, b);
    }

    return TreeFunction(x, y);
  }

  void Merge(int node) {
    int left_son = 2 * node;
    int right_son = 2 * node + 1;

    segment_[node] = TreeFunction(segment_[left_son], segment_[right_son]);
  }

  T TreeFunction(const T x, const T y) const {
    return (x > y) ? x : y;
  }

  vector<T> segment_;
  const int size_;
};

int main() {
  cin.sync_with_stdio(false);

  ifstream cin("pq.in");
  ofstream cout("pq.out");

  int n, q;
  cin >> n >> q;

  vector<int> a(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }

  vector<Query> queries;
  for (int i = 0; i < q; i++) {
    int x, y;
    cin >> x >> y;
    queries.emplace_back(x, y, i);
  }

  sort(all(queries));

  SegmentTree<int> seg(n);
  unordered_map<int, int> last;

  int last_r = 0;
  vector<int> ans(q);
  for (auto it : queries) {
    for (int i = last_r + 1; i <= it.y; i++) {
      int where = last[a[i]];
      if (where) {
        seg.Update(where, i - where);
      }
      last[a[i]] = i;
    }

    ans[it.i] = seg.Query(it.x, it.y);
    last_r = it.y;
  }

  for (auto it : ans) {
    cout << it << '\n';
  }

  return 0;
}