#include <bits/stdc++.h>
using namespace std;
template <class T>
using vec = vector<T>;
template <class T>
using pql = priority_queue<T, vector<T>, greater<T>>;
string debug_show(pair<int, int> a) {
  return "(" + to_string(a.first) + "," + to_string(a.second) + ")";
}
void dump_func() { cerr << endl; }
template <class Head, class... Tail>
void dump_func(Head&& head, Tail&&... tail) {
  cerr << head;
  if (sizeof...(Tail) <= 1) {
    cerr << " ";
  } else {
    cerr << ", ";
  }
  dump_func(std::move(tail)...);
}
template <typename T>
istream& operator>>(istream& is, vector<T>& vec) {
  for (T& x : vec) is >> x;
  return is;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, pair<T, U>& pair_var) {
  os << "(" << pair_var.first << "," << pair_var.second << ")";
  return os;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& pair_var) {
  os << "(" << pair_var.first << "," << pair_var.second << ")";
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& vec) {
  os << "{";
  for (int i = 0; i < vec.size(); i++) {
    os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
  }
  os << "}";
  return os;
}
template <typename T, typename U>
ostream& operator<<(ostream& os, map<T, U>& map_var) {
  os << "{";
  for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
    os << "(" << itr->first << "," << itr->second << ")";
    itr++;
    if (itr == map_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
template <typename T>
ostream& operator<<(ostream& os, set<T>& set_var) {
  os << "{";
  for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
    os << "  " << *itr << endl;
    itr++;
    if (itr == set_var.end()) os << ", ";
    itr--;
  }
  os << "}";
  return os;
}
string YN(bool y, int id = 0) {
  if (id) cout << id;
  return (y ? "YES" : "NO");
}
string yn(bool y, int id = 0) {
  if (id) cout << id;
  return (y ? "Yes" : "No");
}
string ON(bool y, int id = 0) {
  if (id) cout << id;
  return (y ? "OK" : "NG");
}
int dir4[4][2] = {{0, -1}, {-1, 0}, {1, 0}, {0, 1}};
int dir8[8][2] = {{-1, -1}, {0, -1}, {1, -1}, {-1, 0},
                  {1, 0},   {-1, 1}, {0, 1},  {1, 1}};
int irand(int a, int b) {
  static mt19937 Rand(static_cast<unsigned int>(time(nullptr)));
  uniform_int_distribution<int> dist(a, b - 1);
  return dist(Rand);
}
double drand(int a, int b) {
  static mt19937 Rand(static_cast<unsigned int>(time(nullptr)));
  uniform_real_distribution<double> dist(a, b);
  return dist(Rand);
}
struct Edge {
  int from, to, cost;
};
using Graph = vec<vec<Edge>>;
int main() {
  int N;
  cin >> N;
  vector<long long> a(N);
  cin >> a;
  map<long long, int> num;
  num[0] = 1;
  num[a[0]] = 1;
  if (a[0] == 0) num[0]++;
  for (int i = (int)(1); i < (int)(N); i++) {
    a[i] += a[i - 1];
    if (num.find(a[i]) == num.end()) {
      num[a[i]] = 1;
    } else {
      num[a[i]]++;
    }
  }
  long long ans = 0;
  for (auto p : num) {
    if (p.second <= 1) continue;
    ans += p.second * (p.second - 1) / 2;
  }
  cout << ans << endl;
  return 0;
}
