Cod sursa(job #2475027)

Utilizator ApostolIlieDanielApostol Daniel ApostolIlieDaniel Data 16 octombrie 2019 08:29:00
Problema Cuburi2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.53 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 = 1e18;

int n;

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

int h[MAXN + 1];
int good;
void preprocesare () {
  int i;
  for (i = 1; i <= n; i++)
    s1[i] = s1[i - 1] + h[i];
  for (i = 1; i <= n; i++)
    st[i] = st[i - 1] + 1LL * h[i] * i;
}

inline pair <long long, long long> sol (int copst, int l, int r) {
  if (copst < l || copst > r)
    return {INF, INF};
  long long valst = (s1[copst - 1] - s1[l - 1]) * copst - (st[copst - 1] - st[l - 1]);
  long long valdr = (st[r] - st[copst]) - (s1[r] - s1[copst]) * copst;
  return {valst, valdr};
}

inline long long solve (int l, int r) {
  long long mn;
  int st = l;
  int dr = r;
  mn = sol (l, l, r).first + sol (l, l, r).second;
  good = l;
  while (st <= dr) {
    int mid = (st + dr) / 2;
    auto rez = sol (mid, l, r);
    if (mn > rez.first + rez.second) {
        mn = rez.first + rez.second;
        good = mid;
    }
    if (rez.first < rez.second)
        st = mid + 1;
    else
        dr = mid - 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);
    long long sol = solve (l, r);
    fprintf (fout, "%d %lld\n", good, sol);
  }
  fclose (fin);
  fclose (fout);
  return 0;
}