Cod sursa(job #1708563)

Utilizator cercVianuCerc Vianu cercVianu Data 27 mai 2016 13:27:28
Problema A+B Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.91 kb
#include <cstdio>
#include <cassert>

struct Nod {
  long long suma;
  long long dimensiune;
  long long adaugare;

  Nod* fiuSt;
  Nod* fiuDr;
};

template <class Type, int size>
class Prealloc {
private:
  Type data[size];
  Type* addresses[size];
  int available;

public:
  Prealloc() {
    this->available = size;
    int i;
    for (i = 0; i < size; ++i) {
      this->addresses[i] = &this->data[i];
    }
  }

  Type* newType() {
    --this->available;
    return this->addresses[this->available];
  }

  void deleteType(Type* address) {
    this->addresses[this->available] = address;
    ++this->available;
  }
};

Prealloc<Nod, 2800000> alloc;

Nod* arboreGol = nullptr;

Nod* creeazaNod(long long adaugare, Nod* fiuSt, Nod* fiuDr) {
  Nod* answer = alloc.newType();
  if (fiuSt == arboreGol)
    *answer = Nod {
      adaugare,
      1,
      adaugare,
      fiuSt,
      fiuDr};
  else
    *answer = Nod {
      fiuSt->suma + fiuDr->suma + adaugare * (fiuSt->dimensiune + fiuDr->dimensiune),
      fiuSt->dimensiune + fiuDr->dimensiune,
      adaugare,
      fiuSt,
      fiuDr};
  return answer;
}

Nod* construieste(int* inceput, int* sfarsit) {
  int N = sfarsit - inceput;
  if (N == 1)
    return creeazaNod(*inceput, arboreGol, arboreGol);
  return creeazaNod(0,
      construieste(inceput, inceput + (N / 2)),
      construieste(inceput + (N / 2), sfarsit));
}

// query(de la 0 la 2 inclusiv)
// adica i = 0, j = 3
// dimensiune = 6
// 0 1 2 3 4 5

// query(de la 3 la 5 inclusiv)
// adica i = 3, j = 6

Nod* actualizare(Nod* arbore, int L, int R, int V) {
  // interval = [0, arebore->dimensiune)
  assert(0 <= L && L < R && R <= arbore->dimensiune);
  if (L == 0 && R == arbore->dimensiune)
    return creeazaNod(
        arbore->adaugare + V,
        arbore->fiuSt,
        arbore->fiuDr);
  else if (R <= arbore->fiuSt->dimensiune)
    return creeazaNod(
        arbore->adaugare,
        actualizare(
            arbore->fiuSt,
            L,
            R,
            V),
        arbore->fiuDr);
  else if (arbore->fiuSt->dimensiune <= L)
    return creeazaNod(
        arbore->adaugare,
        arbore->fiuSt,
        actualizare(
            arbore->fiuDr,
            L - arbore->fiuSt->dimensiune,
            R - arbore->fiuSt->dimensiune,
            V));
  else
    return creeazaNod(
        arbore->adaugare,
        actualizare(
            arbore->fiuSt,
            L,
            arbore->fiuSt->dimensiune,
            V),
        actualizare(
            arbore->fiuDr,
            0,
            R - arbore->fiuSt->dimensiune,
            V));
}

long long interogare(Nod* arbore, int i, int j) {
  // interval = [0, arebore->dimensiune)
  assert(0 <= i && i < j && j <= arbore->dimensiune);
  if (i == 0 && j == arbore->dimensiune)
    return arbore->suma;
  else if (j <= arbore->fiuSt->dimensiune)
    return arbore->adaugare * (j - i) +
        interogare(arbore->fiuSt, i, j);
  else if (arbore->fiuSt->dimensiune <= i)
    return arbore->adaugare * (j - i) +
        interogare(arbore->fiuDr,
          i - arbore->fiuSt->dimensiune,
          j - arbore->fiuSt->dimensiune);
  else
    return arbore->adaugare * (j - i) +
        interogare(arbore->fiuSt,
          i,
          arbore->fiuSt->dimensiune) +
        interogare(arbore->fiuDr,
          0,
          j - arbore->fiuSt->dimensiune);
}

int main(void) {
  freopen("ants.in", "r", stdin);
  freopen("ants.out", "w", stdout);
  int N, M;

  scanf("%d%d", &N, &M);
  int *A = new int[M];
  for (int i = 0; i < M; ++i) {
    scanf("%d", &A[i]);
  }
  long long S = 0;
  Nod** orase = new Nod*[1 + N];
  orase[1] = construieste(A, A + M);
  for (int ver = 2; ver <= N; ver++) {
    int P, X, Y, V, Z, T;
    scanf("%d%d%d%d%d%d", &P, &X, &Y, &V, &Z, &T);
    int L = (X + S) % M;
    int R = (Y + S) % M;
    int i = (Z + S) % M;
    int j = (T + S) % M;
    orase[ver] = actualizare(orase[P], L, R + 1, V);
    S = interogare(orase[ver], i, j + 1);
    printf("%lld\n", S);
  }
  return 0;
}