Submission #859150

#TimeUsernameProblemLanguageResultExecution timeMemory
859150mircea_007Sum Zero (RMI20_sumzero)C++17
61 / 100
277 ms20884 KiB
#include <stdio.h>
#include <algorithm>

using ll = long long;

const int MAXN = 400000;
//const int MAXQ = 400000;

const int INF = 1e9;

struct Range {
  int st, dr;
} ranges[1 + MAXN];
int nranges;

int next[MAXN];
int jump[MAXN];
int depth[MAXN];

ll sp[1 + MAXN];
int ord[1 + MAXN];

// primul i astfel incat ranges[i].st >= x
int next_after( int x ){
  int st = -1, dr = nranges, mij; // ranges[nranges] e santinela

  while( dr - st > 1 ){
    mij = (st + dr) >> 1;
    
    if( ranges[mij].st >= x )
      dr = mij;
    else
      st = mij;
  }

  return dr;
}

int query( int qst, int qdr ){
  int u = next_after( qst );

  int lowest = depth[u];

  while( ranges[u].dr <= qdr ){
    if( ranges[jump[u]].dr <= qdr )
      u = jump[u];
    else
      u = next[u];
  }

  return lowest - depth[u];
}

int main(){
  int n;

  scanf( "%d", &n );

  sp[0] = 0;
  ord[0] = 0;
  for( int i = 1 ; i <= n ; i++ ){
    scanf( "%lld", sp + i );

    sp[i] += sp[i - 1];
    ord[i] = i;
  }

  std::sort( ord, ord + n + 1, []( int a, int b ) -> bool {
    if( sp[a] != sp[b] )
      return sp[a] < sp[b];

    return a < b;
  } );

  nranges = 0; // global pentru next_after()
  for( int i = 1 ; i < n + 1 ; i++ )
    if( sp[ord[i - 1]] == sp[ord[i]] )
      ranges[nranges++] = Range{ ord[i - 1], ord[i] - 1 };

  std::sort( ranges, ranges + nranges, []( const Range &a, const Range &b ) -> bool {
    return a.st < b.st; // nu se intampla ca a.st == b.st
  } );

  int smallest_dr = INF;
  for( int i = nranges ; i-- ; ){ // mark bad intervals
    if( ranges[i].dr > smallest_dr )
      ranges[i] = Range{ INF, INF };
    else
      smallest_dr = ranges[i].dr;
  }

  // remove marked intervals
  nranges = std::remove_if( ranges, ranges + nranges, []( const Range &a ) -> bool {
    return a.st == INF;
  } ) - ranges;

  ranges[nranges] = Range{ INF, INF };

  next[nranges] = jump[nranges] = nranges;
  depth[nranges] = 0;

  // binary lifting
  for( int i = nranges ; i-- ; ){
    int p = next_after( ranges[i].dr + 1 );

    next[i] = p;
    depth[i] = 1 + depth[p];

    if( depth[p] - depth[jump[p]] == depth[jump[p]] - depth[jump[jump[p]]] )
      jump[i] = jump[jump[p]];
    else
      jump[i] = p;
  }

  int q;
  for( scanf( "%d", &q ) ; q-- ; ){
    int qst, qdr;

    scanf( "%d%d", &qst, &qdr );
    qst--;
    qdr--;

    printf( "%d\n", query( qst, qdr ) );
  }

  return 0;
}

Compilation message (stderr)

sumzero.cpp: In function 'int main()':
sumzero.cpp:57:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   57 |   scanf( "%d", &n );
      |   ~~~~~^~~~~~~~~~~~
sumzero.cpp:62:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   62 |     scanf( "%lld", sp + i );
      |     ~~~~~^~~~~~~~~~~~~~~~~~
sumzero.cpp:116:13: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  116 |   for( scanf( "%d", &q ) ; q-- ; ){
      |        ~~~~~^~~~~~~~~~~~
sumzero.cpp:119:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  119 |     scanf( "%d%d", &qst, &qdr );
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...