Cod sursa(job #2815822)

Utilizator mihaipriboimihailucapriboi mihaipriboi Data 10 decembrie 2021 14:41:36
Problema SequenceQuery Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.45 kb
#include <stdio.h>
#include <algorithm>

#define MAXN 100000
#define INF 10000000000

long long v[MAXN + 1];
struct interval { int st, dr; } aint[MAXN];

void construct( int l, int r, int node ) {
  int leftChild, rightChild, middle;
  middle = (r + l) / 2;
  leftChild = node + 1;
  rightChild = node + 2 * ( middle - l + 1 );

  if( l == r )
    aint[node] = {l, r};
  else {
    int st1, dr1, st2, dr2, st_max, dr_max;
    long long maxim;

    construct( l, middle, leftChild );
    construct( middle + 1, r, rightChild );

    st1 = aint[leftChild].st;
    dr1 = aint[leftChild].dr;
    st2 = aint[rightChild].st;
    dr2 = aint[rightChild].dr;

    maxim = v[dr1] - v[st1 - 1];
    st_max = st1;
    dr_max = dr1;
    if( v[dr2] - v[st2 - 1] > maxim ) {
      maxim = v[dr2] - v[st2 - 1];
      st_max = st2;
      dr_max = dr2;
    }

    if( v[dr2] - v[st1 - 1] > maxim ) {
      maxim = v[dr2] - v[st1 - 1];
      st_max = st1;
      dr_max = dr2;
    }

    aint[node] = {st_max, dr_max};
  }
}

interval getMax( int a, int b, int l, int r, int node ) {
  if( l == a && r == b )
    return aint[node];

  int leftChild, rightChild, middle;
  interval left, right, mx;
  long long maxim;

  middle = (r + l) / 2;
  leftChild = node + 1;
  rightChild = node + 2 * ( middle - l + 1 );

  maxim = -INF;
  if( a <= middle ) {
    left = getMax( a, std::min( middle, b ), l, middle, leftChild );
    maxim = v[left.dr] - v[left.st - 1];
    mx = left;
  }
  if( b > middle ) {
    right = getMax( std::max( middle + 1, a ), b, middle + 1, r, rightChild );
    if( v[right.dr] - v[right.st - 1] > maxim ) {
      maxim = v[right.dr] - v[right.st - 1];
      mx = right;
    }
  }

  if( a <= middle && b > middle && v[right.dr] - v[left.st - 1] > maxim ) {
    maxim = v[right.dr] - v[left.st - 1];
    mx = {left.st, right.dr};
  }

  return mx;
}

int main() {
  FILE *fin, *fout;
  int n, m, i, a, b;
  interval x;

  fin = fopen( "sequencequery.in", "r" );

  fscanf( fin, "%d%d", &n, &m );
  for( i = 1; i <= n; i++ ) {
    fscanf( fin, "%lld", &v[i] );
    v[i] += v[i - 1];
  }

  construct(1, n, 0);

  fout = fopen( "sequencequery.out", "w" );

  for( i = 0; i < m; i++ ) {
    fscanf( fin, "%d%d", &a, &b );
    x = getMax(a, b, 1, n, 0);
    printf( "%d %d\n", x.st, x.dr );
    fprintf( fout, "%lld\n", v[x.dr] - v[x.st - 1] );
  }

  fclose( fin );
  fclose( fout );
  return 0;
}