#include <memory>
#include <utility>

using i64 = long long;

int rand() {
  return 0;
}

struct treap {
  struct node;
  using pointer = std::unique_ptr<node>;
  struct node {
    int priority;
    i64 key, value;
    pointer left, right;

    node(i64 key) : priority(rand()), key(key), value(0), left(), right() {}
  };

  pointer merge(pointer left, pointer right) {
    if (!left) {
      return std::move(right);
    }
    if (!right) {
      return std::move(left);
    }
    if (left->priority > right->priority) {
      left->right = merge(std::move(left->right), std::move(right));
      return std::move(left);
    } else {
      right->left = merge(std::move(left), std::move(right->left));
      return std::move(right);
    }
  }

  using P = std::pair<pointer, pointer>;

  P split(pointer ptr, i64 key) {
    if (!ptr) {
      return {};
    }
    if (key <= ptr->key) {
      P temp = split(std::move(ptr->left), key);
      ptr->left = std::move(temp.second);
      return {std::move(temp.first), std::move(ptr)};
    } else {
      P temp = split(std::move(ptr->right), key);
      ptr->right = std::move(temp.first);
      return {std::move(ptr), std::move(temp.second)};
    }
  }

  pointer root;

  i64 &access(i64 key) {
    P lt = split(std::move(root), key);
    P rt = split(std::move(lt.second), key + 1);
    if (!rt.first) {
      rt.first = std::make_unique<node>(key);
    }
    i64 &ret = rt.first->value;
    lt.second = merge(std::move(rt.first), std::move(rt.second));
    root = merge(std::move(lt.first), std::move(lt.second));
    return ret;
  }
};

#include <iostream>

int main() {
  int n;
  std::cin >> n;
  treap t;
  i64 acc = 0;
  i64 ans = 0;
  ++t.access(0);

  for (int i = 0; i < n; ++i) {
    i64 a;
    std::cin >> a;
    ans += t.access(acc += a)++;
  }

  std::cout << ans << std::endl;

  return 0;
}
