Cod sursa(job #2283516)

Utilizator ApostolIlieDanielApostol Daniel ApostolIlieDaniel Data 15 noiembrie 2018 16:29:30
Problema Cuburi2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.43 kb
#include <bits/stdc++.h>

using namespace std;

FILE *fin = fopen ("cuburi2.in", "r"), *fout = fopen ("cuburi2.out", "w");

const int MAXN = 320000;
long long INF = 1e14;

int n;

long long st[MAXN + 1], dr[MAXN + 1], s1[MAXN + 1], s2[MAXN + 1];

int h[MAXN + 1];

void preprocesare () {
  int i;
  for (i = 1; i <= n; i++)
    s1[i] = s1[i - 1] + h[i];
  for (i = n; i > 0; i--)
    s2[i] = s2[i + 1] + h[i];
  for (i = 1; i <= n; i++)
    st[i] = st[i - 1] + s1[i - 1];
  for (i = n; i > 0; i--)
    dr[i] = dr[i + 1] + s2[i + 1];
}

long long sol (int copst, int l, int r) {
  int valst = st[copst] - st[l - 1] - s1[l - 1] * (copst - l);
  int valdr = dr[copst] - dr[r + 1] - (s2[r + 1]) * (r - copst);
  return valst + valdr;
}

inline long long solve (int l, int r) {
  long long mn;
  int left = l;
  int right = r;
  // cautare ternara
  mn = INF;
  while (left <= right) {
    int lf = left + (right - left) / 3;
    int rg = right - (right - left) / 3;
    mn = min (mn, min (sol(lf, l, r), sol (rg, l, r)));
    if (sol(lf, l, r) > sol (rg, l, r)) {
      left = lf + 1;
    }
    else {
      right = rg - 1;
    }
  }
  return mn;
}

int main() {
  int q, l, r;
  fscanf (fin, "%d%d", &n, &q);
  for (int i = 1; i <= n; i++)
    fscanf (fin, "%d", &h[i]);
  preprocesare ();
  while (q--) {
    fscanf (fin, "%d%d", &l, &r);
    fprintf (fout, "%lld\n", solve (l, r));
  }
  return 0;
}