Cod sursa(job #1713108)

Utilizator stoianmihailStoian Mihail stoianmihail Data 4 iunie 2016 18:35:40
Problema Pq Scor 0
Compilator cpp Status done
Runda Arhiva ICPC Marime 3.15 kb
#include <stdio.h>
#include <ctype.h>
#include <vector>

using std::vector;

#define treeSize 131072
#define Nadejde 100000
#define Dragoste 65536

struct reff {
  int v, b, e;
};

struct cell {
  int max;
  vector <reff> key;
};

int max, ptr;
cell tree[2 * treeSize];
int seen[Nadejde], last[Nadejde];

FILE *f;
char buff[Dragoste];
int pos = Dragoste;

inline char getChar() {
  if (pos == Dragoste) {
    fread(buff, 1, Dragoste, f);
    pos = 0;
  }
  return buff[pos++];
}

inline int freef() {
  int result = 0;
  char c;

  do {
    c = getChar();
  } while (!isdigit(c));
  do {
    result = (result << 3) + (result << 1) + c - '0';
    c = getChar();
  } while (isdigit(c));
  return result;
}

/*
void afis(cell x) {
  fprintf(stderr, "%d: ", x.max);
  for (int i = 0; i < x.key.size(); i++) {
    fprintf(stderr, "%d -> (%d, %d) ", x.key[i].v, x.key[i].b, x.key[i].e);
  }
  fprintf(stderr, "\n");
}
*/

inline int MAX(int X, int Y) {
  return X > Y ? X : Y;
}

inline void create(int u) {
  int i = 0, j = 0, son = 2 * u;

  tree[u].max = MAX(tree[son].max, tree[son + 1].max);
  while (i < tree[son].key.size() && j < tree[son + 1].key.size()) {
    if (tree[son].key[i].v < tree[son + 1].key[j].v) {
      tree[u].key.push_back(tree[son].key[i]);
      i++;
    } else if (tree[son].key[i].v > tree[son + 1].key[j].v) {
      tree[u].key.push_back(tree[son + 1].key[j]);
      j++;
    } else {
      tree[u].key.push_back((reff)
      {
          tree[son].key[i].v, 
          tree[son].key[i].b,
          tree[son + 1].key[j].e
      });
      tree[u].max = MAX(tree[u].max, tree[son + 1].key[j].b - tree[son].key[i].e);
      i++;
      j++;
    }
  }
  while (i < tree[son].key.size()) {
    tree[u].key.push_back(tree[son].key[i]);
    i++;
  }
  while (j < tree[son + 1].key.size()) {
    tree[u].key.push_back(tree[son + 1].key[j]);
    j++;
  }
}

inline void build(int u, int left, int right) {
  if (left == right) {
    tree[u].key.push_back((reff){freef(), left, left});
    return;
  }

  int mid = (left + right) / 2;
  build(2 * u, left, mid);
  build(2 * u + 1, mid + 1, right);
  create(u);
}

inline void query(int u, int left, int right, int a, int b) {
  if (a <= left && right <= b) {
    int i;
    if (tree[u].max > max) {
      max = tree[u].max;
    }
    for (i = 0; i < tree[u].key.size(); i++) {
      if (seen[tree[u].key[i].v] == ptr && tree[u].key[i].b - last[tree[u].key[i].v] > max) {
        max = tree[u].key[i].b - last[tree[u].key[i].v];
      }
      seen[tree[u].key[i].v] = ptr;
      last[tree[u].key[i].v] = tree[u].key[i].e;
    }
    return;
  }

  int mid = (left + right) / 2;
  if (a <= mid) {
    query(2 * u, left, mid, a, b);
  }
  if (b > mid) {
    query(2 * u + 1, mid + 1, right, a, b);
  }
}

int main(void) {
  int N, Q, a, b;
  f = fopen("pq.in", "r");

  N = freef();
  Q = freef();
  build(1, 1, N);
/*
  afis(tree[1]);

  afis(tree[4]);
  afis(tree[10]);
*/
  freopen("pq.out", "w", stdout);
  while (Q) {
    ptr++;
    a = freef();
    b = freef();
    max = 0;
    query(1, 1, N, a, b);
    fprintf(stdout, "%d\n", max == 0 ? -1 : max);
    Q--;
  }
  fclose(f);
  fclose(stdout);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}