Cod sursa(job #1492336)

Utilizator stoianmihailStoian Mihail stoianmihail Data 27 septembrie 2015 16:34:05
Problema Deque Scor 60
Compilator c Status done
Runda Arhiva educationala Marime 3.31 kb
#include <time.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

#define R 16777215
#define MAX_VALUE 10000001
#define Nadejde 15000000
#define Smerenie 5000000
#define Dragoste 4096
#define MAX_LEVEL 25

int N, K;
int val[Smerenie];            // vectorul nostru.
int bufPtr, level;            // nivelul maxim in structura.
int pos = Dragoste;           // pozitia in buffer.
int update[MAX_LEVEL];        // folosit in timpul inserarii.
int sl[Nadejde + MAX_LEVEL];  // zona de memorie prealocata.
char c, sign, buff[Dragoste]; // bufferul oferit de sistem.

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

/** 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);
  }
}

/** Initializeaza structura. **/
void init() {
  sl[0] = -MAX_VALUE;
  sl[MAX_LEVEL + 1] = MAX_VALUE;

  int l;
  for (l = 1; l <= MAX_LEVEL; l++) {
    sl[l] = MAX_LEVEL + 1;
  }
  bufPtr = MAX_LEVEL + 2;
  level = 1;
}

/** Da-mi un nivel random. **/
int randomLevel() {
  int l = 1, r;
  for (r = rand() & R; r & 1; r >>= 1) {
    l++;
  }
  return l;
}

/** Insereaza valoarea "x" in structura. **/
void insert(int x) {
  int l, pos = 0;

  /* Cauta pointerii ce trebuie actualizati. */
  for (l = level - 1; l >= 0; l--) {
    while (sl[sl[pos + l + 1]] < x) {
      pos = sl[pos + l + 1];
    }
    update[l] = pos;
  }

  int newLevel = randomLevel();
  if (newLevel > level) {
    for (l = level; l < newLevel; l++) {
      update[l] = 0;
    }
    level = newLevel;
  }

  /* Introdu-l pe "x" in structura, restabilind pointerii. */
  sl[bufPtr] = x;
  for (l = 0; l < newLevel; l++) {
    sl[bufPtr + l + 1] = sl[update[l] + l + 1];
    sl[update[l] + l + 1] = bufPtr;
  }
  bufPtr += newLevel + 1;
}

/** Sterge valoarea "x" din structura. **/
void erase(int x) {
  int l, pos = 0;
  for (l = level - 1; l >= 0; l--) {
    while (sl[sl[pos + l + 1]] < x) {
      pos = sl[pos + l + 1];
    }
    update[l] = pos;
  }
  pos = sl[pos + 1];

  l = 0;
  while ((l < level) && (sl[update[l] + l + 1] == pos)) {
    sl[update[l] + l + 1] = sl[pos + l + 1];
    l++;
  }
}

/** Da-mi minimul. **/
int minHeap() {
  return sl[sl[1]];
}

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

  init();
  srand(time(NULL));

  /* Citeste sirul dat pana la "K". **/
  freef(f, "%d", &N);
  freef(f, "%d", &K);
  for (i = 0; i < K; i++) {
    freef(f, "%d", &val[i]);
    insert(val[i]);

    if (val[i] < min) {
      min = val[i];
    }
  }

  /* Determina minimul din fiecare secventa de lungime "K". **/
  long long int sum = min;
  for (i = K; i < N; i++) {
    freef(f, "%d", &val[i]);

    insert(val[i]);
    erase(val[i - K]);
    sum += minHeap();
  }
  fclose(f);

  f = fopen("deque.out", "w");
  fprintf(f, "%lld\n", sum);
  fclose(f);

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