//prewritten code: https://github.com/antma/algo
import std.algorithm;
import std.array;
import std.conv;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.traits;
import std.typecons;

final class InputReader {
  private:
  ubyte[] p, buffer;
  bool eof;
  bool rawRead () {
    if (eof) {
      return false;
    }
    p = stdin.rawRead (buffer);
    if (p.empty) {
      eof = true;
      return false;
    }
    return true;
  }
  ubyte nextByte(bool check) () {
    static if (check) {
      if (p.empty) {
        if (!rawRead ()) {
          return 0;
        }
      }
    }
    auto r = p.front;
    p.popFront ();
    return r;
  }
  public:
  this () {
    buffer = uninitializedArray!(ubyte[])(16<<20);
  }
  bool seekByte (in ubyte lo) {
    while (true) {
      p = p.find! (c => c >= lo);
      if (!p.empty) {
        return false;
      }
      if (!rawRead ()) {
        return true;
      }
    }
  }
  template next(T) if (isSigned!T) {
    T next ()  {
      if (seekByte (45)) {
        return 0;
      }
      T res;
      ubyte b = nextByte!false ();
      if (b == 45) {
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 - (b - 48);
        }
      } else {
        res = b - 48;
        while (true) {
          b = nextByte!true ();
          if (b < 48 || b >= 58) {
            return res;
          }
          res = res * 10 + (b - 48);
        }
      }
    }
  }
  template next(T) if (isUnsigned!T) {
    T next () {
      if (seekByte (48)) {
        return 0;
      }
      T res = nextByte!false () - 48;
      while (true) {
        ubyte b = nextByte!true ();
        if (b < 48 || b >= 58) {
          break;
        }
        res = res * 10 + (b - 48);
      }
      return res;
    }
  }
  T[] nextA(T) (in int n) {
    auto a = uninitializedArray!(T[]) (n);
    foreach (i; 0 .. n) {
      a[i] = next!T;
    }
    return a;
  }
}

alias T = Tuple!(long, uint);

void main() {
  auto r = new InputReader ();
  const n = r.next!uint;
  auto a = r.nextA!int (n);
  const s = sum (a, 0L);
  //prefix[i] + suffix[j] + a[i .. j] == s 
  //prefix[i] + suffix[j] == s
  auto pr = new long[n+1];
  pr[0] = 0;
  foreach (i; 1 .. n + 1) pr[i] = pr[i-1] + a[i-1];
  /*
  auto sf = new long[n+1];
  sf[n] = 0;
  foreach_reverse (i; 0 .. n) sf[i] = sf[i+1] + a[i];
  */
  T[] x;
  x.reserve (n + 1);
  foreach (i; 0 .. n + 1) x ~= tuple (pr[i], i);
  sort (x);
  debug stderr.writeln ("pr = ", pr);
  debug stderr.writeln ("x = ", x);
  int i;
  auto z = new uint[n+1];
  z[] = uint.max;
  while (i < x.length) {
    int j = i + 1;
    while (j < x.length && x[i][0] == x[j][0]) ++j;
    uint last = uint.max;
    foreach_reverse (const ref q; x[i .. j]) {
      debug stderr.writeln (q);
      if (last != uint.max) {
        z[q[1]] = last - 1;
      }
      last = q[1];
    }
    i = j;
  }
  debug stderr.writeln ("z = ", z);
  foreach_reverse (k; 0 .. n) {
    z[k] = min (z[k+1], z[k]);
  }
  debug stderr.writeln ("z = ", z);
  long res;
  foreach (k; 0 .. n) {
    z[k] = min (z[k], n);
    if (z[k] > k) {
      res += z[k] - k;
    }
  }
  writeln (res);
}

