Cod sursa(job #2475087)

Utilizator ivan.tudorIvan Tudor ivan.tudor Data 16 octombrie 2019 11:01:31
Problema Cuburi2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.67 kb

#include <bits/stdc++.h>

using namespace std;
//#define fin stdin
//#define fout stdout
FILE *fin = fopen ("cuburi2.in", "r"), *fout = fopen ("cuburi2.out", "w");

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

int n;

long long st[MAXN + 1], dr[MAXN + 1], sl[MAXN + 1];

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

inline long long val (int copst, int l, int r) {
  if (copst < l || copst > r)
    return INF;
  long long valst = st[copst] - st[l] - (copst - l) * (sl[l - 1]);
  long long valdr = dr[copst] - dr[r] - (r - copst) * (sl[n] - sl[r]);
  return valst + valdr;
}

inline int solve (int l, int r) {
  int ll = l;
  int rr = r;
  int good = l;
  while (ll <= rr) {
    int mid = (ll + rr) / 2;
    long long valst = st[mid] - st[l] - (mid - l) * (sl[l - 1]);
    long long valdr = dr[mid - 1] - dr[r] - (r - mid + 1) * (sl[n] - sl[r]);

    if (valst < valdr) {
        good = mid;
        ll = mid + 1;
    }
    else
        rr = mid - 1;
  }
  return good;
}

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);
    int sol = solve (l, r);
    if (val (sol, l, r) < val (sol + 1, l, r))
        fprintf (fout, "%d %lld\n", sol, val (sol, l, r));
    else
        fprintf (fout, "%d %lld\n", sol + 1, val (sol + 1, l, r));
  }
  fclose (fin);
  fclose (fout);
  return 0;
}