Cod sursa(job #1492372)

Utilizator stoianmihailStoian Mihail stoianmihail Data 27 septembrie 2015 17:08:41
Problema Deque Scor 60
Compilator c Status done
Runda Arhiva educationala Marime 2.89 kb
#include <stdio.h>
#include <ctype.h>

#define MAX_VALUE 10000000
#define Nadejde 5000001
#define aibSize 5000000
#define Lg 4194304
#define Dragoste 4096
#define NIL -1

typedef struct {
  int v, pos;
} cell;

int N, K;
int val[Nadejde];             // vectorul nostru.
int p = Dragoste;             // pozitia in buffer.
int pos[Nadejde];             // pos[i] este pozitia in "save" a elementului care a fost oarecand pe pozitia "i" in vectorul initial.
cell save[Nadejde];           // retine pozitiile si valorile initiale.
int fen[aibSize + 1];         // aib.
char c, sign, buff[Dragoste]; // bufferul oferit de sistem.

/** Ia urmatorul caracter din fisier. **/
char getChar(FILE *f) {
  if (p == Dragoste) {
    fread(buff, 1, Dragoste, f);
    p = 0;
  }
  return buff[p++];
}

/** Citeste urmatorul numar din fisier. **/
void freef(FILE *f, const char *type, int *result) {
  *result = 0;
  c = '#';
  do {
    sign = c;
    c = getChar(f);
  } while (!isdigit(c));
  do {
    *result = (*result << 3) + (*result << 1) + c - '0';
    c = getChar(f);
  } while (isdigit(c));

  if (sign == '-') {
    *result = -(*result);
  }
}

/** Sorteaza structura "save". **/
void sort(int begin, int end) {
  int b = begin, e = end, pivot = save[(b + e) >> 1].v;
  while (b <= e) {
    while (save[b].v < pivot) {
      b++;
    }
    while (save[e].v > pivot) {
      e--;
    }
    if (b <= e) {
      cell tmp = save[b];
      save[b++] = save[e];
      save[e--] = tmp;
    }
  }
  if (b < end) {
    sort(b, end);
  }
  if (begin < e) {
    sort(begin, e);
  }
}

/** Normalizeaza structura. **/
void normalize() {
  int i;
  sort(1, N);
  for (i = 1; i <= N; i++) {
    pos[save[i].pos] = i;
  }
}

/** Adauga in aib. **/
void add(int x, int val) {
  do {
    fen[x] += val;
    x += x & -x;
  } while (x <= aibSize);
}

/** Cauta binar minimul. **/
int bSearch(int k) {
  int x = 0, interval;
  for (interval = Lg; interval; interval >>= 1) {
    if (fen[x + interval] < k) {
      k -= fen[x + interval];
      x += interval;
    }
  }
  return x + 1;
}

int main(void) {
  int i;
  FILE *f = fopen("deque.in", "r");

  /* Citeste vectorul. **/
  freef(f, "%d", &N);
  freef(f, "%d", &K);
  for (i = 1; i <= N; i++) {
    freef(f, "%d", &val[i]);
    save[i].v = pos[i] = val[i];
    save[i].pos = i;
  }
  fclose(f);

  f = fopen("deque.out", "w");

  normalize();

  /** Raspunde pentru fiecare secventa de lungime "K". **/
  int min = MAX_VALUE;
  for (i = 1; i <= K; i++) {
    if (val[i] < min) {
      min = val[i];
    }
    add(pos[i], -NIL);
  }
  long long int sum = min;
  for (i = K + 1; i <= N; i++) {
    add(pos[i], -NIL);
    add(pos[i - K], NIL);

    sum += save[bSearch(-NIL)].v;
  }
  fprintf(f, "%lld", sum);
  fclose(f);

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