#include <bits/stdc++.h>

using namespace std;

// somethings maybe wrong in template, did not veryify everything pay attention.
// update template regularly
// < (template) >
// < (defines) >
#define ar array
#define ll long long
#define ld long double
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int)(x).size()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define lbi(A,x)   (lower_bound(A.begin(),A.end(), x) - A.begin())
#define ubi(A,x)   (upper_bound(A.begin(), A.end(), x) - A.begin())
#define lbir(A,i,j,x)  (lower_bound(A.begin() + i , A.begin() + j , x) - A.begin())
#define ubir(A,i,j,x)  (upper_bound(A.begin() + i, A.begin() + j, x) - A.begin())
#define f_prec(prec)  cout << fixed << setprecision(prec) ;
#define vv(A, T, n1, n2, val) vector<vector<T>> A(n1, vector<T>(n2, val))
#define vvv(A, T, n1, n2, n3, val) vector<vector<vector<T>>> A(n1, vector<vector<T>>(n2, vector<T>(n3, val)))
#define vvvv(A, T, n1, n2, n3, n4, val) vector<vector<vector<vector<T>>>> A(n1, vector<vector<vector<T>>>(n2, vector<vector<T>>(n3, vector<T>(n4, val))))
// </ (defines)>
// <(debugging template) >
template <typename A, typename B>
string to_string(pair<A, B> p);
template <typename T>
string to_string(stack <T> st);
template <typename T>
string to_string(queue<T> q);
string to_string(char c){return string(1, c);}
string to_string(const string s){return '"' + s + '"';}
string to_string(const char* s){return to_string((string)s);}
string to_string(bool b){return (b ? "true" : "false");}
string to_string(vector<bool> v){bool first = true;string res = "{";for (int i = 0; i < static_cast<int>(v.size()); i++) {if (!first) {res += ", ";}first = false;res += to_string(v[i]);}res += "}";return res;}
// prints bitset just like a vector (not number)
template <size_t S>
string to_string(bitset<S> b){string res;res += '{';bool f = true;for (int i = 0; i < S; ++i) {if (!f) {res += ',';}f = false;res += char('0' + b[i]);}res += '}';return res;}
template <typename A>
string to_string(A v){bool first = true;string res = "{";for (const auto& x : v) {if (!first) {res += ", ";}first = false;res += to_string(x);}res += "}";return res;}
template <typename A, typename B>
string to_string(pair<A, B> p){return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";}
template <typename T >
string to_string(stack <T> st){bool first = true;string res = "{";while (!st.empty()) {if (!first) {res += ", ";}first = false;res += to_string(st.top());st.pop();}res += "}";return res;}
template <typename T>
string to_string(queue<T> q){bool first = true;string res = "{";while (!q.empty()) {if (!first) {res += ", ";}first = false;res += to_string(q.front());q.pop();}res += "}";return res;}
template <typename T>
string to_string(T pq, bool ispq){assert(ispq); bool first = true;string res = "{";while (!pq.empty()) {if (!first) {res += ", ";}first = false;res += to_string(pq.top());pq.pop();}res += "}";return res;}
// tuple deleted from template
void DBG(){cerr << " ]" << "\n";}
template <typename Head, typename... Tail>
void DBG(Head H, Tail... T){cerr << " " << to_string(H);if (sizeof...(T)) {cerr << ", ";}DBG(T...);}

#ifdef zxcv_1
#define dbg(...) cerr << "L(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 42
#endif
// <(/debugging template)>
// < (datastrucures) >
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T>
using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename key, typename value, typename cmp = std::less<key>>
using omap = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// </ (datastructures) >
// < (loops) >
#define fr(i,a,b,d) for (int i = a; i < b; i += d)
#define rfr(i,b,a,d) for(int i= b; i>= a; i -= d)
#define frc(i,a,b,c,d) for(int i = a; (i< b) && c ; i += d)
#define rfrc(i,a,b,c,d) for(int i = b; (i>= a) && c ; i -= d)
// </ (loops) >
// < (reading) >
void read(char &x) {cin >> x;}
void read(int& x){cin >> x;}
void read(ll& x){cin >> x;}
void read(double& x){cin >> x;}
void read(string& s){cin >> s;}
// works only for simple pairs  <int,int>, <string,int> .....
template <typename T1, typename T2>
void read(pair<T1, T2>& p){cin >> p.first >> p.second;}
template <typename T>
void read(T& A){for (auto& x : A) {read(x);}}
template <typename T>
void assign_offset(T& A, int off = -1){for (auto& x : A) {x += off;}}
template <class H, class... T>
void read(H& h, T&... t){read(h);read(t...);}
// </ (reading) >
// < (writing) >
// where T must be simple
template <typename T>
void out (T &A, int offset = 0 ){for(auto &x : A){x += offset; cout <<  x <<" ";}cout <<"\n"; }
// </ (writing) >
// < (functions) >
#define fsttrue(lo_val,hi_val,valid,ansi) {ll lo = lo_val , hi = hi_val,  mid;while (lo <= hi) {mid = lo + (hi - lo) / 2;if (valid(mid)) {ansi = mid;hi = mid - 1;} else {lo = mid + 1;}}}
#define lsttrue(lo_val,hi_val,valid,ansi) {ll lo = lo_val , hi = hi_val,  mid;while (lo <= hi) {mid = lo + (hi - lo) / 2;if (valid(mid)) {ansi = mid;lo = mid + 1;} else {hi = mid - 1;}}}
#define ternint_hi(lo_val,hi_val,gv,ansi,ansv) {ll lo = lo_val, hi = hi_val, m1, m2;const int diffrange = 7;while (hi - lo > diffrange) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) < gv(m2)) {    lo = m1;} else {    hi = m2;}}ansi = lo;ansv = gv(lo);for (int i = lo + 1; i <= hi; ++i) {if (a_max(ansv, gv(i))) {    ansi = i;}}}
#define ternint_lo(lo_val,hi_val,gv,ansi,ansv) {ll lo = lo_val, hi = hi_val, m1, m2;const int diffrange = 7;while (hi - lo > diffrange) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) > gv(m2)) {    lo = m1;} else {    hi = m2;}}ansi = lo;ansv = gv(lo);for (int i = lo + 1; i <= hi; ++i) {if (a_min(ansv, gv(i))) {    ansi = i;}}}
#define terndouble_hi(lo_val,hi_val,gv,ansi,ansv) {double lo = lo_val, hi = hi_val, m1, m2;const double eps = 1e-9; while (hi - lo > eps) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) < gv(m2)) {lo = m1;} else {hi = m2;}}double ansi = lo;double ansv = gv(lo);}
#define terndouble_lo(lo_val,hi_val,gv,ansi,ansv) {double lo = lo_val, hi = hi_val, m1, m2;const double eps = 1e-9; while (hi - lo > eps) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) > gv(m2)) {lo = m1;} else {hi = m2;}}double ansi = lo;double ansv = gv(lo);}
// random in [l,r]
mt19937 mt_rng(chrono::steady_clock::now().time_since_epoch().count());ll rand_m(ll a, ll b){return uniform_int_distribution<ll>(a, b)(mt_rng);}
// assign min of (a,b) , if (a > b) return true and assigns a = b
template <typename T>
bool a_min(T& a, const T& b){return (b < a) ? (a = b), 1 : 0;}
// assign max of (a,b) ,if (a < b) return true and assigns a = b
template <typename T>
bool a_max(T& a, const T& b){return (b > a) ? (a = b), 1 : 0;}
// both m and n must be positive
ll ceil(ll m, ll n){return (m + n - 1) / n;}
// 0 based index
// getval , [i, j] sum using prefix
template<typename T>
ll gv(int i, int j, vector<T>& pre){if (i > j || (j < 0)) {return 0LL;}ll val = pre[j];if (i - 1 >= 0) {val -= pre[i - 1];}return val;}
// getprefixval , [0...i] sum
template <typename T>
ll gpv(int i, vector<T>& pre){return gv(0, i, pre);}
// getsuffixval, [i....n - 1] sum
template <typename T>
ll gsv(int i, vector<T>& suf){int n = sz(suf);if (i >= n) {return 0LL;}return suf[i];}
// assigns values to   prefix array with indices 0 to n-1
template<typename T>
void assign_pre(vector<T>& pre, vector<T>& A){int n = sz(A);for (int i = 0; i < n; ++i) {pre[i] = A[i];if (i) {pre[i] += pre[i - 1];}}}
// assigns values  suffix array with indices 0 to n-1
template<typename T>
void assign_suf(vector<T>& suf, vector<T>& A){int n = sz(A);for (int i = n - 1; i >= 0; --i) {suf[i] = A[i];if (i + 1 < n) {suf[i] += suf[i + 1];}}}
// finds no of values between [l,r]
template <typename T>
int sorted_range (const vector<T>& A , int l , int r){int n = A.size(); if (r < l){return 0 ;}return ubi(A,r) - ubi(A,l-1); }
// sorts and removes duplicates from vector
template <typename T>
void remove_dup(vector<T>& v){sort(all(v));v.erase(unique(all(v)), v.end());}
// returns no of 1's in binary representation
constexpr int ppcnt(int x){return __builtin_popcount(x);}
constexpr int ppcnt(ll x){return __builtin_popcountll(x);}
// returns floor(log2(x))
constexpr int f_lg(int x){return 31 - __builtin_clz(x);}
constexpr int f_lg(ll x){return 63 - __builtin_clzll(x);}
// </ (functions) >
// </ (template)>

#ifdef zxcv_1
auto start = std::chrono::system_clock::now();
#endif

// < (modify if needed) >
const ld PI = acos((ld)-1);
const ll inf = 2e18;
const ll ninf = -2e18;

const int M = 1e9 + 7;
// const int M =  998244353;

#define ret_g() cout << "Good" << "\n"; return;
#define ret_b() cout << "Bad" << "\n"; return;

// no need to set multiple_test_cases if code_jam flag is set
bool code_jam = 0;

bool multiple_test_cases =  0;

// </ (modify if needed) >

// (write main logic here)

class stree {

    struct snode
    {

        ll val;

        ll delta;

        snode(ll x)
        {
            val = x;
            delta = 0;
        }

        ll getVal()
        {
            return val + delta;
        }
    };

public :

    vector<ll> L , R , A  ;
    vector<snode> ST ;

    int n ;
    stree (vector<ll>& a ){
        A = a;
        n = a.size();
        L.resize(4*n);
        R.resize(4*n);
        ST = vector<snode> (4*n , snode(1e18));
        init(1 , 0 , n - 1);
    }

    void init (int i , int l , int r){

        L[i] = l ;
        R[i] = r;

        if (l == r){
            ST[i] = snode(A[l]);
            return;
        }

        ll mid = (l + r)/ 2;
        init(2*i , l , mid);
        init(2*i + 1 , mid + 1 , r);

        merge(i);

    }

    void propogate (int i ){

        ST[2*i].delta += ST[i].delta;
        ST[2*i + 1].delta += ST[i].delta;
    }
    void merge (int i ){

        ST[i].val = min(ST[2*i].getVal() , ST[2*i +1].getVal());
        ST[i].delta = 0 ;
    }
    void update (int i , int l , int r, ll x){
        if (R[i] < l || r < L[i]){
            return;
        }

        if (l <= L[i] && R[i] <= r){
            ST[i].delta +=  x;
            return ;
        }

        propogate(i);
        update(2*i , l , r, x);
        update(2*i + 1 , l , r, x);
        merge(i);
    }

    void update(int l , int r , ll x){
        update(1 , l , r , x);
    }

    ll getval (int i , int l , int r){

        if (R[i] < l || r < L[i] ){
            return 1e18 ;
        }

        if (l <= L[i] && R[i] <= r){
            return ST[i].getVal();
        }

        propogate(i);

        ll left  = getval(2* i , l , r);
        ll right = getval(2 * i + 1 , l, r);

        merge(i);

        return min(left , right);

    }

    ll getval(int l , int r){
        return getval(1 , l , r);
    }

    ll findminind (int i , ll x ){

        if (L[i] == R[i]){
            return L[i];
        }

        if (getval(2*i , L[2*i] , R[2*i] ) == x){
            return findminind (2 * i , x);
        }

        return  findminind(2*i + 1,x);

    }

    ll findminind(ll x){
        return findminind(1 , x);
    }

    // 4444333222222221
    ll findind (int i , ll x){

        // dbg(i , L[i], R[i], ST[i].getVal(),  x);

        if (L[i] == R[i] ){

            if (ST[i].getVal() == x){
                return L[i];
            }
            assert(false);
            return -1;
        }

        propogate(i);

        merge(i);

        ll lt =  ST[2*i].getVal();

        // dbg(lt, x);
        if (lt <= x){
            return findind(2*i, x);
        }

        return findind(2*i + 1 , x);

    }
    ll findind (ll x){
        return findind(1 , x);
    }

};

class stree_a {

    struct snode
    {

        ll val;

        ll delta;

        snode(ll x)
        {
            val = x;
            delta = 0;
        }

        ll getVal(ll L, ll R)
        {
            return val + (R - L + 1) * delta;
        }
    };

public :

    vector<ll> L , R , A  ;
    vector<snode> ST ;

    int n ;
    stree_a (vector<ll>& a ){
        A = a;
        n = a.size();
        L.resize(4*n);
        R.resize(4*n);
        ST = vector<snode> (4*n , snode(0));
        init(1 , 0 , n - 1);
    }

    void init (int i , int l , int r){

        L[i] = l ;
        R[i] = r;

        if (l == r){
            ST[i] = snode(A[l]);
            return;
        }

        ll mid = (l + r)/ 2;
        init(2*i , l , mid);
        init(2*i + 1 , mid + 1 , r);

        merge(i);

    }

    void propogate (int i ){
        ST[2*i].delta += ST[i].delta;
        ST[2*i + 1].delta += ST[i].delta;
    }

    void merge (int i ){

        ST[i].val = ST[2*i].getVal(L[2*i], R[2*i]) +  ST[2*i + 1].getVal(L[2*i + 1], R[2*i + 1]);
        ST[i].delta = 0 ;
    }

    void update (int i , int l , int r, ll x){
        if (R[i] < l || r < L[i]){
            return;
        }

        if (l <= L[i] && R[i] <= r){
            ST[i].delta +=  x;
            return ;
        }

        propogate(i);
        update(2*i , l , r, x);
        update(2*i + 1 , l , r, x);
        merge(i);
    }

    void update(int l , int r , ll x){
        update(1 , l , r , x);
    }

    ll getval (int i , int l , int r){

        if (R[i] < l || r < L[i] ){
            return 0 ;
        }

        if (l <= L[i] && R[i] <= r){
            return ST[i].getVal(L[i], R[i]);
        }

        propogate(i);

        ll left  = getval(2* i , l , r);
        ll right = getval(2 * i + 1 , l, r);

        merge(i);

        return left + right ;

    }

    ll getval(int l , int r){
        return getval(1 , l , r);
    }

};

void solve(){

    int n ;
    cin >> n  ;

    string s;
    cin >> s;

    vector<ll> A (n);

    stree st_m (A);

    stree_a st_a (A);

    ll ans = 0;

    vector<int>  ones(n);

    for(int i = 0 ; i < n ;++i){

        if (s[i] == '0'){
            ans +=  st_a.getval(0 , n -1);
            ones[i] = 0;
            continue;
        }

        if (i){
            ones[i] =  ones[i - 1] + 1;
        }
        else{
            ones[i] = 1;
        }

        cout <<"-------------------------------------------------------" <<"\n";
        cout <<"i : "<< i << "\n";
        int ind =  st_m.findind(ones[i] - 1);

        st_a.update(ind, i , 1);
        st_m.update(ind , i, 1);

        dbg(ones[i] - 1 , ind, i, st_a.getval(0 , n -1));

        ans +=  st_a.getval(0,  n -1);

        dbg(st_m.ST[8].getVal(), st_m.L[8] , st_m.R[8]);

        cout << "--------------------------------------------------------" <<"\n";

    }

    cout << ans <<"\n";

}

// main function
int main()
{

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int T = 1 ;

    if (code_jam){
        multiple_test_cases =  true;
    }

    if(multiple_test_cases){
        cin >> T;
    }

    for (int t = 1; t <= T; ++t) {
        if(t == 1){
            #ifdef zxcv_1
                start = std::chrono::system_clock::now();
            #endif
        }
        if(code_jam)
            cout << "Case #" << t << ": ";
        solve();
    }

    #ifdef zxcv_1
        auto end = std::chrono::system_clock::now();
        std::chrono::duration<double> elapsed_seconds = end - start;
        std::cerr << "Elapsed time: " << elapsed_seconds.count() << "s\n";
    #endif

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

// somethings maybe wrong in template, did not veryify everything pay attention.
// update template regularly
// < (template) >
// < (defines) >
#define ar array
#define ll long long
#define ld long double
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int)(x).size()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define lbi(A,x)   (lower_bound(A.begin(),A.end(), x) - A.begin())
#define ubi(A,x)   (upper_bound(A.begin(), A.end(), x) - A.begin())
#define lbir(A,i,j,x)  (lower_bound(A.begin() + i , A.begin() + j , x) - A.begin())
#define ubir(A,i,j,x)  (upper_bound(A.begin() + i, A.begin() + j, x) - A.begin())
#define f_prec(prec)  cout << fixed << setprecision(prec) ;
#define vv(A, T, n1, n2, val) vector<vector<T>> A(n1, vector<T>(n2, val))
#define vvv(A, T, n1, n2, n3, val) vector<vector<vector<T>>> A(n1, vector<vector<T>>(n2, vector<T>(n3, val)))
#define vvvv(A, T, n1, n2, n3, n4, val) vector<vector<vector<vector<T>>>> A(n1, vector<vector<vector<T>>>(n2, vector<vector<T>>(n3, vector<T>(n4, val))))
// </ (defines)>
// <(debugging template) >
template <typename A, typename B>
string to_string(pair<A, B> p);
template <typename T>
string to_string(stack <T> st);
template <typename T>
string to_string(queue<T> q);
string to_string(char c){return string(1, c);}
string to_string(const string s){return '"' + s + '"';}
string to_string(const char* s){return to_string((string)s);}
string to_string(bool b){return (b ? "true" : "false");}
string to_string(vector<bool> v){bool first = true;string res = "{";for (int i = 0; i < static_cast<int>(v.size()); i++) {if (!first) {res += ", ";}first = false;res += to_string(v[i]);}res += "}";return res;}
// prints bitset just like a vector (not number)
template <size_t S>
string to_string(bitset<S> b){string res;res += '{';bool f = true;for (int i = 0; i < S; ++i) {if (!f) {res += ',';}f = false;res += char('0' + b[i]);}res += '}';return res;}
template <typename A>
string to_string(A v){bool first = true;string res = "{";for (const auto& x : v) {if (!first) {res += ", ";}first = false;res += to_string(x);}res += "}";return res;}
template <typename A, typename B>
string to_string(pair<A, B> p){return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";}
template <typename T >
string to_string(stack <T> st){bool first = true;string res = "{";while (!st.empty()) {if (!first) {res += ", ";}first = false;res += to_string(st.top());st.pop();}res += "}";return res;}
template <typename T>
string to_string(queue<T> q){bool first = true;string res = "{";while (!q.empty()) {if (!first) {res += ", ";}first = false;res += to_string(q.front());q.pop();}res += "}";return res;}
template <typename T>
string to_string(T pq, bool ispq){assert(ispq); bool first = true;string res = "{";while (!pq.empty()) {if (!first) {res += ", ";}first = false;res += to_string(pq.top());pq.pop();}res += "}";return res;}
// tuple deleted from template
void DBG(){cerr << " ]" << "\n";}
template <typename Head, typename... Tail>
void DBG(Head H, Tail... T){cerr << " " << to_string(H);if (sizeof...(T)) {cerr << ", ";}DBG(T...);}

#ifdef zxcv_1
#define dbg(...) cerr << "L(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 42
#endif
// <(/debugging template)>
// < (datastrucures) >
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T>
using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename key, typename value, typename cmp = std::less<key>>
using omap = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// </ (datastructures) >
// < (loops) >
#define fr(i,a,b,d) for (int i = a; i < b; i += d)
#define rfr(i,b,a,d) for(int i= b; i>= a; i -= d)
#define frc(i,a,b,c,d) for(int i = a; (i< b) && c ; i += d)
#define rfrc(i,a,b,c,d) for(int i = b; (i>= a) && c ; i -= d)
// </ (loops) >
// < (reading) >
void read(char &x) {cin >> x;}
void read(int& x){cin >> x;}
void read(ll& x){cin >> x;}
void read(double& x){cin >> x;}
void read(string& s){cin >> s;}
// works only for simple pairs  <int,int>, <string,int> .....
template <typename T1, typename T2>
void read(pair<T1, T2>& p){cin >> p.first >> p.second;}
template <typename T>
void read(T& A){for (auto& x : A) {read(x);}}
template <typename T>
void assign_offset(T& A, int off = -1){for (auto& x : A) {x += off;}}
template <class H, class... T>
void read(H& h, T&... t){read(h);read(t...);}
// </ (reading) >
// < (writing) >
// where T must be simple
template <typename T>
void out (T &A, int offset = 0 ){for(auto &x : A){x += offset; cout <<  x <<" ";}cout <<"\n"; }
// </ (writing) >
// < (functions) >
#define fsttrue(lo_val,hi_val,valid,ansi) {ll lo = lo_val , hi = hi_val,  mid;while (lo <= hi) {mid = lo + (hi - lo) / 2;if (valid(mid)) {ansi = mid;hi = mid - 1;} else {lo = mid + 1;}}}
#define lsttrue(lo_val,hi_val,valid,ansi) {ll lo = lo_val , hi = hi_val,  mid;while (lo <= hi) {mid = lo + (hi - lo) / 2;if (valid(mid)) {ansi = mid;lo = mid + 1;} else {hi = mid - 1;}}}
#define ternint_hi(lo_val,hi_val,gv,ansi,ansv) {ll lo = lo_val, hi = hi_val, m1, m2;const int diffrange = 7;while (hi - lo > diffrange) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) < gv(m2)) {    lo = m1;} else {    hi = m2;}}ansi = lo;ansv = gv(lo);for (int i = lo + 1; i <= hi; ++i) {if (a_max(ansv, gv(i))) {    ansi = i;}}}
#define ternint_lo(lo_val,hi_val,gv,ansi,ansv) {ll lo = lo_val, hi = hi_val, m1, m2;const int diffrange = 7;while (hi - lo > diffrange) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) > gv(m2)) {    lo = m1;} else {    hi = m2;}}ansi = lo;ansv = gv(lo);for (int i = lo + 1; i <= hi; ++i) {if (a_min(ansv, gv(i))) {    ansi = i;}}}
#define terndouble_hi(lo_val,hi_val,gv,ansi,ansv) {double lo = lo_val, hi = hi_val, m1, m2;const double eps = 1e-9; while (hi - lo > eps) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) < gv(m2)) {lo = m1;} else {hi = m2;}}double ansi = lo;double ansv = gv(lo);}
#define terndouble_lo(lo_val,hi_val,gv,ansi,ansv) {double lo = lo_val, hi = hi_val, m1, m2;const double eps = 1e-9; while (hi - lo > eps) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) > gv(m2)) {lo = m1;} else {hi = m2;}}double ansi = lo;double ansv = gv(lo);}
// random in [l,r]
mt19937 mt_rng(chrono::steady_clock::now().time_since_epoch().count());ll rand_m(ll a, ll b){return uniform_int_distribution<ll>(a, b)(mt_rng);}
// assign min of (a,b) , if (a > b) return true and assigns a = b
template <typename T>
bool a_min(T& a, const T& b){return (b < a) ? (a = b), 1 : 0;}
// assign max of (a,b) ,if (a < b) return true and assigns a = b
template <typename T>
bool a_max(T& a, const T& b){return (b > a) ? (a = b), 1 : 0;}
// both m and n must be positive
ll ceil(ll m, ll n){return (m + n - 1) / n;}
// 0 based index
// getval , [i, j] sum using prefix
template<typename T>
ll gv(int i, int j, vector<T>& pre){if (i > j || (j < 0)) {return 0LL;}ll val = pre[j];if (i - 1 >= 0) {val -= pre[i - 1];}return val;}
// getprefixval , [0...i] sum
template <typename T>
ll gpv(int i, vector<T>& pre){return gv(0, i, pre);}
// getsuffixval, [i....n - 1] sum
template <typename T>
ll gsv(int i, vector<T>& suf){int n = sz(suf);if (i >= n) {return 0LL;}return suf[i];}
// assigns values to   prefix array with indices 0 to n-1
template<typename T>
void assign_pre(vector<T>& pre, vector<T>& A){int n = sz(A);for (int i = 0; i < n; ++i) {pre[i] = A[i];if (i) {pre[i] += pre[i - 1];}}}
// assigns values  suffix array with indices 0 to n-1
template<typename T>
void assign_suf(vector<T>& suf, vector<T>& A){int n = sz(A);for (int i = n - 1; i >= 0; --i) {suf[i] = A[i];if (i + 1 < n) {suf[i] += suf[i + 1];}}}
// finds no of values between [l,r]
template <typename T>
int sorted_range (const vector<T>& A , int l , int r){int n = A.size(); if (r < l){return 0 ;}return ubi(A,r) - ubi(A,l-1); }
// sorts and removes duplicates from vector
template <typename T>
void remove_dup(vector<T>& v){sort(all(v));v.erase(unique(all(v)), v.end());}
// returns no of 1's in binary representation
constexpr int ppcnt(int x){return __builtin_popcount(x);}
constexpr int ppcnt(ll x){return __builtin_popcountll(x);}
// returns floor(log2(x))
constexpr int f_lg(int x){return 31 - __builtin_clz(x);}
constexpr int f_lg(ll x){return 63 - __builtin_clzll(x);}
// </ (functions) >
// </ (template)>

#ifdef zxcv_1
auto start = std::chrono::system_clock::now();
#endif

// < (modify if needed) >
const ld PI = acos((ld)-1);
const ll inf = 2e18;
const ll ninf = -2e18;

const int M = 1e9 + 7;
// const int M =  998244353;

#define ret_g() cout << "Good" << "\n"; return;
#define ret_b() cout << "Bad" << "\n"; return;

// no need to set multiple_test_cases if code_jam flag is set
bool code_jam = 0;

bool multiple_test_cases =  0;

// </ (modify if needed) >

// (write main logic here)

void solve(){

    int n ;
    cin >> n  ;

    string s;
    cin >> s;

    vector<ll> A (n);

    vector<int>  ones(n);

    vector<int> pos (n + 1 , -1);

    pos[0] = 0;

    ll ans = 0;

    ll tot = 0;

    for(int i = 0 ; i < n ;++i){

        if (s[i] == '0'){
            ans +=  tot;
            ones[i] = 0;
            continue;
        }

        if (i){
            ones[i] =  ones[i - 1] + 1;
        }
        else{
            ones[i] = 1;
        }

        tot +=  i - pos[ones[i]];

        ans +=  tot;

        if (i + 1 < n &&  s[i +1 ] == '0'){

            int len =  ones[i];

            for(int j  = i; j >= i - len; --j){
                pos[i - j + 1] = j;
            }
        }

    }

    cout << ans <<"\n";

}

// main function
int main()
{

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int T = 1 ;

    if (code_jam){
        multiple_test_cases =  true;
    }

    if(multiple_test_cases){
        cin >> T;
    }

    for (int t = 1; t <= T; ++t) {
        if(t == 1){
            #ifdef zxcv_1
                start = std::chrono::system_clock::now();
            #endif
        }
        if(code_jam)
            cout << "Case #" << t << ": ";
        solve();
    }

    #ifdef zxcv_1
        auto end = std::chrono::system_clock::now();
        std::chrono::duration<double> elapsed_seconds = end - start;
        std::cerr << "Elapsed time: " << elapsed_seconds.count() << "s\n";
    #endif

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

// somethings maybe wrong in template, did not veryify everything pay attention.
// update template regularly
// < (template) >
// < (defines) >
#define ar array
#define ll long long
#define ld long double
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int)(x).size()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define lbi(A,x)   (lower_bound(A.begin(),A.end(), x) - A.begin())
#define ubi(A,x)   (upper_bound(A.begin(), A.end(), x) - A.begin())
#define lbir(A,i,j,x)  (lower_bound(A.begin() + i , A.begin() + j , x) - A.begin())
#define ubir(A,i,j,x)  (upper_bound(A.begin() + i, A.begin() + j, x) - A.begin())
#define f_prec(prec)  cout << fixed << setprecision(prec) ;
#define vv(A, T, n1, n2, val) vector<vector<T>> A(n1, vector<T>(n2, val))
#define vvv(A, T, n1, n2, n3, val) vector<vector<vector<T>>> A(n1, vector<vector<T>>(n2, vector<T>(n3, val)))
#define vvvv(A, T, n1, n2, n3, n4, val) vector<vector<vector<vector<T>>>> A(n1, vector<vector<vector<T>>>(n2, vector<vector<T>>(n3, vector<T>(n4, val))))
// </ (defines)>
// <(debugging template) >
template <typename A, typename B>
string to_string(pair<A, B> p);
template <typename T>
string to_string(stack <T> st);
template <typename T>
string to_string(queue<T> q);
string to_string(char c){return string(1, c);}
string to_string(const string s){return '"' + s + '"';}
string to_string(const char* s){return to_string((string)s);}
string to_string(bool b){return (b ? "true" : "false");}
string to_string(vector<bool> v){bool first = true;string res = "{";for (int i = 0; i < static_cast<int>(v.size()); i++) {if (!first) {res += ", ";}first = false;res += to_string(v[i]);}res += "}";return res;}
// prints bitset just like a vector (not number)
template <size_t S>
string to_string(bitset<S> b){string res;res += '{';bool f = true;for (int i = 0; i < S; ++i) {if (!f) {res += ',';}f = false;res += char('0' + b[i]);}res += '}';return res;}
template <typename A>
string to_string(A v){bool first = true;string res = "{";for (const auto& x : v) {if (!first) {res += ", ";}first = false;res += to_string(x);}res += "}";return res;}
template <typename A, typename B>
string to_string(pair<A, B> p){return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";}
template <typename T >
string to_string(stack <T> st){bool first = true;string res = "{";while (!st.empty()) {if (!first) {res += ", ";}first = false;res += to_string(st.top());st.pop();}res += "}";return res;}
template <typename T>
string to_string(queue<T> q){bool first = true;string res = "{";while (!q.empty()) {if (!first) {res += ", ";}first = false;res += to_string(q.front());q.pop();}res += "}";return res;}
template <typename T>
string to_string(T pq, bool ispq){assert(ispq); bool first = true;string res = "{";while (!pq.empty()) {if (!first) {res += ", ";}first = false;res += to_string(pq.top());pq.pop();}res += "}";return res;}
// tuple deleted from template
void DBG(){cerr << " ]" << "\n";}
template <typename Head, typename... Tail>
void DBG(Head H, Tail... T){cerr << " " << to_string(H);if (sizeof...(T)) {cerr << ", ";}DBG(T...);}

#ifdef zxcv_1
#define dbg(...) cerr << "L(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 42
#endif
// <(/debugging template)>
// < (datastrucures) >
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T>
using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename key, typename value, typename cmp = std::less<key>>
using omap = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// </ (datastructures) >
// < (loops) >
#define fr(i,a,b,d) for (int i = a; i < b; i += d)
#define rfr(i,b,a,d) for(int i= b; i>= a; i -= d)
#define frc(i,a,b,c,d) for(int i = a; (i< b) && c ; i += d)
#define rfrc(i,a,b,c,d) for(int i = b; (i>= a) && c ; i -= d)
// </ (loops) >
// < (reading) >
void read(char &x) {cin >> x;}
void read(int& x){cin >> x;}
void read(ll& x){cin >> x;}
void read(double& x){cin >> x;}
void read(string& s){cin >> s;}
// works only for simple pairs  <int,int>, <string,int> .....
template <typename T1, typename T2>
void read(pair<T1, T2>& p){cin >> p.first >> p.second;}
template <typename T>
void read(T& A){for (auto& x : A) {read(x);}}
template <typename T>
void assign_offset(T& A, int off = -1){for (auto& x : A) {x += off;}}
template <class H, class... T>
void read(H& h, T&... t){read(h);read(t...);}
// </ (reading) >
// < (writing) >
// where T must be simple
template <typename T>
void out (T &A, int offset = 0 ){for(auto &x : A){x += offset; cout <<  x <<" ";}cout <<"\n"; }
// </ (writing) >
// < (functions) >
#define fsttrue(lo_val,hi_val,valid,ansi) {ll lo = lo_val , hi = hi_val,  mid;while (lo <= hi) {mid = lo + (hi - lo) / 2;if (valid(mid)) {ansi = mid;hi = mid - 1;} else {lo = mid + 1;}}}
#define lsttrue(lo_val,hi_val,valid,ansi) {ll lo = lo_val , hi = hi_val,  mid;while (lo <= hi) {mid = lo + (hi - lo) / 2;if (valid(mid)) {ansi = mid;lo = mid + 1;} else {hi = mid - 1;}}}
#define ternint_hi(lo_val,hi_val,gv,ansi,ansv) {ll lo = lo_val, hi = hi_val, m1, m2;const int diffrange = 7;while (hi - lo > diffrange) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) < gv(m2)) {    lo = m1;} else {    hi = m2;}}ansi = lo;ansv = gv(lo);for (int i = lo + 1; i <= hi; ++i) {if (a_max(ansv, gv(i))) {    ansi = i;}}}
#define ternint_lo(lo_val,hi_val,gv,ansi,ansv) {ll lo = lo_val, hi = hi_val, m1, m2;const int diffrange = 7;while (hi - lo > diffrange) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) > gv(m2)) {    lo = m1;} else {    hi = m2;}}ansi = lo;ansv = gv(lo);for (int i = lo + 1; i <= hi; ++i) {if (a_min(ansv, gv(i))) {    ansi = i;}}}
#define terndouble_hi(lo_val,hi_val,gv,ansi,ansv) {double lo = lo_val, hi = hi_val, m1, m2;const double eps = 1e-9; while (hi - lo > eps) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) < gv(m2)) {lo = m1;} else {hi = m2;}}double ansi = lo;double ansv = gv(lo);}
#define terndouble_lo(lo_val,hi_val,gv,ansi,ansv) {double lo = lo_val, hi = hi_val, m1, m2;const double eps = 1e-9; while (hi - lo > eps) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) > gv(m2)) {lo = m1;} else {hi = m2;}}double ansi = lo;double ansv = gv(lo);}
// random in [l,r]
mt19937 mt_rng(chrono::steady_clock::now().time_since_epoch().count());ll rand_m(ll a, ll b){return uniform_int_distribution<ll>(a, b)(mt_rng);}
// assign min of (a,b) , if (a > b) return true and assigns a = b
template <typename T>
bool a_min(T& a, const T& b){return (b < a) ? (a = b), 1 : 0;}
// assign max of (a,b) ,if (a < b) return true and assigns a = b
template <typename T>
bool a_max(T& a, const T& b){return (b > a) ? (a = b), 1 : 0;}
// both m and n must be positive
ll ceil(ll m, ll n){return (m + n - 1) / n;}
// 0 based index
// getval , [i, j] sum using prefix
template<typename T>
ll gv(int i, int j, vector<T>& pre){if (i > j || (j < 0)) {return 0LL;}ll val = pre[j];if (i - 1 >= 0) {val -= pre[i - 1];}return val;}
// getprefixval , [0...i] sum
template <typename T>
ll gpv(int i, vector<T>& pre){return gv(0, i, pre);}
// getsuffixval, [i....n - 1] sum
template <typename T>
ll gsv(int i, vector<T>& suf){int n = sz(suf);if (i >= n) {return 0LL;}return suf[i];}
// assigns values to   prefix array with indices 0 to n-1
template<typename T>
void assign_pre(vector<T>& pre, vector<T>& A){int n = sz(A);for (int i = 0; i < n; ++i) {pre[i] = A[i];if (i) {pre[i] += pre[i - 1];}}}
// assigns values  suffix array with indices 0 to n-1
template<typename T>
void assign_suf(vector<T>& suf, vector<T>& A){int n = sz(A);for (int i = n - 1; i >= 0; --i) {suf[i] = A[i];if (i + 1 < n) {suf[i] += suf[i + 1];}}}
// finds no of values between [l,r]
template <typename T>
int sorted_range (const vector<T>& A , int l , int r){int n = A.size(); if (r < l){return 0 ;}return ubi(A,r) - ubi(A,l-1); }
// sorts and removes duplicates from vector
template <typename T>
void remove_dup(vector<T>& v){sort(all(v));v.erase(unique(all(v)), v.end());}
// returns no of 1's in binary representation
constexpr int ppcnt(int x){return __builtin_popcount(x);}
constexpr int ppcnt(ll x){return __builtin_popcountll(x);}
// returns floor(log2(x))
constexpr int f_lg(int x){return 31 - __builtin_clz(x);}
constexpr int f_lg(ll x){return 63 - __builtin_clzll(x);}
// </ (functions) >
// </ (template)>

#ifdef zxcv_1
auto start = std::chrono::system_clock::now();
#endif

// < (modify if needed) >
const ld PI = acos((ld)-1);
const ll inf = 2e18;
const ll ninf = -2e18;

const int M = 1e9 + 7;
// const int M =  998244353;

#define ret_g() cout << "Good" << "\n"; return;
#define ret_b() cout << "Bad" << "\n"; return;

// no need to set multiple_test_cases if code_jam flag is set
bool code_jam = 0;

bool multiple_test_cases =  0;

// </ (modify if needed) >

// (write main logic here)

void solve(){

    int n ;
    cin >> n  ;

    string s;
    cin >> s;

    vector<ll> A (n);

    vector<int>  ones(n);

    vector<int> pos (n + 1 , -1);

    pos[0] = 0;

    ll ans = 0;

    ll tot = 0;

    for(int i = 0 ; i < n ;++i){

        if (s[i] == '0'){

            ans +=  tot;
            dbg(tot);
            ones[i] = 0;
            continue;
        }

        if (i){
            ones[i] =  ones[i - 1] + 1;
        }
        else{
            ones[i] = 1;
        }

        tot +=  i - pos[ones[i]];

        dbg(i , tot);
        dbg(ones[i], pos[ones[i]]);

        ans +=  tot;

        if (i + 1 < n &&  s[i +1 ] == '0'){

            int len =  ones[i];

            for(int j  = i; j >= i - len + 1; --j){
                pos[i - j + 1] = j;
            }
        }

    }

    cout << ans <<"\n";

}

// main function
int main()
{

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int T = 1 ;

    if (code_jam){
        multiple_test_cases =  true;
    }

    if(multiple_test_cases){
        cin >> T;
    }

    for (int t = 1; t <= T; ++t) {
        if(t == 1){
            #ifdef zxcv_1
                start = std::chrono::system_clock::now();
            #endif
        }
        if(code_jam)
            cout << "Case #" << t << ": ";
        solve();
    }

    #ifdef zxcv_1
        auto end = std::chrono::system_clock::now();
        std::chrono::duration<double> elapsed_seconds = end - start;
        std::cerr << "Elapsed time: " << elapsed_seconds.count() << "s\n";
    #endif

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

// somethings maybe wrong in template, did not veryify everything pay attention.
// update template regularly
// < (template) >
// < (defines) >
#define ar array
#define ll long long
#define ld long double
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int)(x).size()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define lbi(A,x)   (lower_bound(A.begin(),A.end(), x) - A.begin())
#define ubi(A,x)   (upper_bound(A.begin(), A.end(), x) - A.begin())
#define lbir(A,i,j,x)  (lower_bound(A.begin() + i , A.begin() + j , x) - A.begin())
#define ubir(A,i,j,x)  (upper_bound(A.begin() + i, A.begin() + j, x) - A.begin())
#define f_prec(prec)  cout << fixed << setprecision(prec) ;
#define vv(A, T, n1, n2, val) vector<vector<T>> A(n1, vector<T>(n2, val))
#define vvv(A, T, n1, n2, n3, val) vector<vector<vector<T>>> A(n1, vector<vector<T>>(n2, vector<T>(n3, val)))
#define vvvv(A, T, n1, n2, n3, n4, val) vector<vector<vector<vector<T>>>> A(n1, vector<vector<vector<T>>>(n2, vector<vector<T>>(n3, vector<T>(n4, val))))
// </ (defines)>
// <(debugging template) >
template <typename A, typename B>
string to_string(pair<A, B> p);
template <typename T>
string to_string(stack <T> st);
template <typename T>
string to_string(queue<T> q);
string to_string(char c){return string(1, c);}
string to_string(const string s){return '"' + s + '"';}
string to_string(const char* s){return to_string((string)s);}
string to_string(bool b){return (b ? "true" : "false");}
string to_string(vector<bool> v){bool first = true;string res = "{";for (int i = 0; i < static_cast<int>(v.size()); i++) {if (!first) {res += ", ";}first = false;res += to_string(v[i]);}res += "}";return res;}
// prints bitset just like a vector (not number)
template <size_t S>
string to_string(bitset<S> b){string res;res += '{';bool f = true;for (int i = 0; i < S; ++i) {if (!f) {res += ',';}f = false;res += char('0' + b[i]);}res += '}';return res;}
template <typename A>
string to_string(A v){bool first = true;string res = "{";for (const auto& x : v) {if (!first) {res += ", ";}first = false;res += to_string(x);}res += "}";return res;}
template <typename A, typename B>
string to_string(pair<A, B> p){return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";}
template <typename T >
string to_string(stack <T> st){bool first = true;string res = "{";while (!st.empty()) {if (!first) {res += ", ";}first = false;res += to_string(st.top());st.pop();}res += "}";return res;}
template <typename T>
string to_string(queue<T> q){bool first = true;string res = "{";while (!q.empty()) {if (!first) {res += ", ";}first = false;res += to_string(q.front());q.pop();}res += "}";return res;}
template <typename T>
string to_string(T pq, bool ispq){assert(ispq); bool first = true;string res = "{";while (!pq.empty()) {if (!first) {res += ", ";}first = false;res += to_string(pq.top());pq.pop();}res += "}";return res;}
// tuple deleted from template
void DBG(){cerr << " ]" << "\n";}
template <typename Head, typename... Tail>
void DBG(Head H, Tail... T){cerr << " " << to_string(H);if (sizeof...(T)) {cerr << ", ";}DBG(T...);}

#ifdef zxcv_1
#define dbg(...) cerr << "L(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 42
#endif
// <(/debugging template)>
// < (datastrucures) >
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T>
using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename key, typename value, typename cmp = std::less<key>>
using omap = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// </ (datastructures) >
// < (loops) >
#define fr(i,a,b,d) for (int i = a; i < b; i += d)
#define rfr(i,b,a,d) for(int i= b; i>= a; i -= d)
#define frc(i,a,b,c,d) for(int i = a; (i< b) && c ; i += d)
#define rfrc(i,a,b,c,d) for(int i = b; (i>= a) && c ; i -= d)
// </ (loops) >
// < (reading) >
void read(char &x) {cin >> x;}
void read(int& x){cin >> x;}
void read(ll& x){cin >> x;}
void read(double& x){cin >> x;}
void read(string& s){cin >> s;}
// works only for simple pairs  <int,int>, <string,int> .....
template <typename T1, typename T2>
void read(pair<T1, T2>& p){cin >> p.first >> p.second;}
template <typename T>
void read(T& A){for (auto& x : A) {read(x);}}
template <typename T>
void assign_offset(T& A, int off = -1){for (auto& x : A) {x += off;}}
template <class H, class... T>
void read(H& h, T&... t){read(h);read(t...);}
// </ (reading) >
// < (writing) >
// where T must be simple
template <typename T>
void out (T &A, int offset = 0 ){for(auto &x : A){x += offset; cout <<  x <<" ";}cout <<"\n"; }
// </ (writing) >
// < (functions) >
#define fsttrue(lo_val,hi_val,valid,ansi) {ll lo = lo_val , hi = hi_val,  mid;while (lo <= hi) {mid = lo + (hi - lo) / 2;if (valid(mid)) {ansi = mid;hi = mid - 1;} else {lo = mid + 1;}}}
#define lsttrue(lo_val,hi_val,valid,ansi) {ll lo = lo_val , hi = hi_val,  mid;while (lo <= hi) {mid = lo + (hi - lo) / 2;if (valid(mid)) {ansi = mid;lo = mid + 1;} else {hi = mid - 1;}}}
#define ternint_hi(lo_val,hi_val,gv,ansi,ansv) {ll lo = lo_val, hi = hi_val, m1, m2;const int diffrange = 7;while (hi - lo > diffrange) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) < gv(m2)) {    lo = m1;} else {    hi = m2;}}ansi = lo;ansv = gv(lo);for (int i = lo + 1; i <= hi; ++i) {if (a_max(ansv, gv(i))) {    ansi = i;}}}
#define ternint_lo(lo_val,hi_val,gv,ansi,ansv) {ll lo = lo_val, hi = hi_val, m1, m2;const int diffrange = 7;while (hi - lo > diffrange) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) > gv(m2)) {    lo = m1;} else {    hi = m2;}}ansi = lo;ansv = gv(lo);for (int i = lo + 1; i <= hi; ++i) {if (a_min(ansv, gv(i))) {    ansi = i;}}}
#define terndouble_hi(lo_val,hi_val,gv,ansi,ansv) {double lo = lo_val, hi = hi_val, m1, m2;const double eps = 1e-9; while (hi - lo > eps) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) < gv(m2)) {lo = m1;} else {hi = m2;}}double ansi = lo;double ansv = gv(lo);}
#define terndouble_lo(lo_val,hi_val,gv,ansi,ansv) {double lo = lo_val, hi = hi_val, m1, m2;const double eps = 1e-9; while (hi - lo > eps) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) > gv(m2)) {lo = m1;} else {hi = m2;}}double ansi = lo;double ansv = gv(lo);}
// random in [l,r]
mt19937 mt_rng(chrono::steady_clock::now().time_since_epoch().count());ll rand_m(ll a, ll b){return uniform_int_distribution<ll>(a, b)(mt_rng);}
// assign min of (a,b) , if (a > b) return true and assigns a = b
template <typename T>
bool a_min(T& a, const T& b){return (b < a) ? (a = b), 1 : 0;}
// assign max of (a,b) ,if (a < b) return true and assigns a = b
template <typename T>
bool a_max(T& a, const T& b){return (b > a) ? (a = b), 1 : 0;}
// both m and n must be positive
ll ceil(ll m, ll n){return (m + n - 1) / n;}
// 0 based index
// getval , [i, j] sum using prefix
template<typename T>
ll gv(int i, int j, vector<T>& pre){if (i > j || (j < 0)) {return 0LL;}ll val = pre[j];if (i - 1 >= 0) {val -= pre[i - 1];}return val;}
// getprefixval , [0...i] sum
template <typename T>
ll gpv(int i, vector<T>& pre){return gv(0, i, pre);}
// getsuffixval, [i....n - 1] sum
template <typename T>
ll gsv(int i, vector<T>& suf){int n = sz(suf);if (i >= n) {return 0LL;}return suf[i];}
// assigns values to   prefix array with indices 0 to n-1
template<typename T>
void assign_pre(vector<T>& pre, vector<T>& A){int n = sz(A);for (int i = 0; i < n; ++i) {pre[i] = A[i];if (i) {pre[i] += pre[i - 1];}}}
// assigns values  suffix array with indices 0 to n-1
template<typename T>
void assign_suf(vector<T>& suf, vector<T>& A){int n = sz(A);for (int i = n - 1; i >= 0; --i) {suf[i] = A[i];if (i + 1 < n) {suf[i] += suf[i + 1];}}}
// finds no of values between [l,r]
template <typename T>
int sorted_range (const vector<T>& A , int l , int r){int n = A.size(); if (r < l){return 0 ;}return ubi(A,r) - ubi(A,l-1); }
// sorts and removes duplicates from vector
template <typename T>
void remove_dup(vector<T>& v){sort(all(v));v.erase(unique(all(v)), v.end());}
// returns no of 1's in binary representation
constexpr int ppcnt(int x){return __builtin_popcount(x);}
constexpr int ppcnt(ll x){return __builtin_popcountll(x);}
// returns floor(log2(x))
constexpr int f_lg(int x){return 31 - __builtin_clz(x);}
constexpr int f_lg(ll x){return 63 - __builtin_clzll(x);}
// </ (functions) >
// </ (template)>

#ifdef zxcv_1
auto start = std::chrono::system_clock::now();
#endif

// < (modify if needed) >
const ld PI = acos((ld)-1);
const ll inf = 2e18;
const ll ninf = -2e18;

const int M = 1e9 + 7;
// const int M =  998244353;

#define ret_g() cout << "Good" << "\n"; return;
#define ret_b() cout << "Bad" << "\n"; return;

// no need to set multiple_test_cases if code_jam flag is set
bool code_jam = 0;

bool multiple_test_cases =  0;

// </ (modify if needed) >

// (write main logic here)

class stree {

    struct snode
    {

        ll val;

        ll delta;

        snode(ll x)
        {
            val = x;
            delta = 0;
        }

        ll getVal()
        {
            return val + delta;
        }
    };

public :

    vector<ll> L , R , A  ;
    vector<snode> ST ;

    int n ;
    stree (vector<ll>& a ){
        A = a;
        n = a.size();
        L.resize(4*n);
        R.resize(4*n);
        ST = vector<snode> (4*n , snode(1e18));
        init(1 , 0 , n - 1);
    }

    void init (int i , int l , int r){

        L[i] = l ;
        R[i] = r;

        if (l == r){
            ST[i] = snode(A[l]);
            return;
        }

        ll mid = (l + r)/ 2;
        init(2*i , l , mid);
        init(2*i + 1 , mid + 1 , r);

        merge(i);

    }

    void propogate (int i ){

        ST[2*i].delta += ST[i].delta;
        ST[2*i + 1].delta += ST[i].delta;
    }
    void merge (int i ){

        ST[i].val = min(ST[2*i].getVal() , ST[2*i +1].getVal());
        ST[i].delta = 0 ;
    }
    void update (int i , int l , int r, ll x){
        if (R[i] < l || r < L[i]){
            return;
        }

        if (l <= L[i] && R[i] <= r){
            ST[i].delta +=  x;
            return ;
        }

        propogate(i);
        update(2*i , l , r, x);
        update(2*i + 1 , l , r, x);
        merge(i);
    }

    void update(int l , int r , ll x){
        update(1 , l , r , x);
    }

    ll getval (int i , int l , int r){

        if (R[i] < l || r < L[i] ){
            return 1e18 ;
        }

        if (l <= L[i] && R[i] <= r){
            return ST[i].getVal();
        }

        propogate(i);

        ll left  = getval(2* i , l , r);
        ll right = getval(2 * i + 1 , l, r);

        merge(i);

        return min(left , right);

    }

    ll getval(int l , int r){
        return getval(1 , l , r);
    }

    ll findminind (int i , ll x ){

        if (L[i] == R[i]){
            return L[i];
        }

        if (getval(2*i , L[2*i] , R[2*i] ) == x){
            return findminind (2 * i , x);
        }

        return  findminind(2*i + 1,x);

    }

    ll findminind(ll x){
        return findminind(1 , x);
    }

    // 4444333222222221
    ll findind (int i , ll x){

        // dbg(i , L[i], R[i], ST[i].getVal(),  x);

        if (L[i] == R[i] ){

            if (ST[i].getVal() == x){
                return L[i];
            }
            assert(false);
            return -1;
        }

        propogate(i);

        merge(i);

        ll lt =  ST[2*i].getVal();

        // dbg(lt, x);
        if (lt <= x){
            return findind(2*i, x);
        }

        return findind(2*i + 1 , x);

    }
    ll findind (ll x){
        return findind(1 , x);
    }

};

class stree_a {

    struct snode
    {

        ll val;

        ll delta;

        snode(ll x)
        {
            val = x;
            delta = 0;
        }

        ll getVal(ll L, ll R)
        {
            return val + (R - L + 1) * delta;
        }
    };

public :

    vector<ll> L , R , A  ;
    vector<snode> ST ;

    int n ;
    stree_a (vector<ll>& a ){
        A = a;
        n = a.size();
        L.resize(4*n);
        R.resize(4*n);
        ST = vector<snode> (4*n , snode(0));
        init(1 , 0 , n - 1);
    }

    void init (int i , int l , int r){

        L[i] = l ;
        R[i] = r;

        if (l == r){
            ST[i] = snode(A[l]);
            return;
        }

        ll mid = (l + r)/ 2;
        init(2*i , l , mid);
        init(2*i + 1 , mid + 1 , r);

        merge(i);

    }

    void propogate (int i ){
        ST[2*i].delta += ST[i].delta;
        ST[2*i + 1].delta += ST[i].delta;
    }

    void merge (int i ){

        ST[i].val = ST[2*i].getVal(L[2*i], R[2*i]) +  ST[2*i + 1].getVal(L[2*i + 1], R[2*i + 1]);
        ST[i].delta = 0 ;
    }

    void update (int i , int l , int r, ll x){
        if (R[i] < l || r < L[i]){
            return;
        }

        if (l <= L[i] && R[i] <= r){
            ST[i].delta +=  x;
            return ;
        }

        propogate(i);
        update(2*i , l , r, x);
        update(2*i + 1 , l , r, x);
        merge(i);
    }

    void update(int l , int r , ll x){
        update(1 , l , r , x);
    }

    ll getval (int i , int l , int r){

        if (R[i] < l || r < L[i] ){
            return 0 ;
        }

        if (l <= L[i] && R[i] <= r){
            return ST[i].getVal(L[i], R[i]);
        }

        propogate(i);

        ll left  = getval(2* i , l , r);
        ll right = getval(2 * i + 1 , l, r);

        merge(i);

        return left + right ;

    }

    ll getval(int l , int r){
        return getval(1 , l , r);
    }

};

void solve(){

    int n ;
    cin >> n  ;

    string s;
    cin >> s;

    vector<ll> A (n);

    stree st_m (A);

    stree_a st_a (A);

    ll ans = 0;

    vector<int>  ones(n);

    for(int i = 0 ; i < n ;++i){

        if (s[i] == '0'){
            ans +=  st_a.getval(0 , n -1);
            ones[i] = 0;
            continue;
        }

        if (i){
            ones[i] =  ones[i - 1] + 1;
        }
        else{
            ones[i] = 1;
        }

        int ind =  st_m.findind(ones[i] - 1);

        st_a.update(ind, i , 1);
        st_m.update(ind , i, 1);

        dbg(ones[i] - 1 , ind, i, st_a.getval(0 , n -1));

        ans +=  st_a.getval(0,  n -1);

        dbg(st_m.ST[8].getVal(), st_m.L[8] , st_m.R[8]);

    }

    cout << ans <<"\n";

}

// main function
int main()
{

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int T = 1 ;

    if (code_jam){
        multiple_test_cases =  true;
    }

    if(multiple_test_cases){
        cin >> T;
    }

    for (int t = 1; t <= T; ++t) {
        if(t == 1){
            #ifdef zxcv_1
                start = std::chrono::system_clock::now();
            #endif
        }
        if(code_jam)
            cout << "Case #" << t << ": ";
        solve();
    }

    #ifdef zxcv_1
        auto end = std::chrono::system_clock::now();
        std::chrono::duration<double> elapsed_seconds = end - start;
        std::cerr << "Elapsed time: " << elapsed_seconds.count() << "s\n";
    #endif

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

// somethings maybe wrong in template, did not veryify everything pay attention.
// update template regularly
// < (template) >
// < (defines) >
#define ar array
#define ll long long
#define ld long double
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int)(x).size()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define lbi(A, x) (lower_bound(A.begin(), A.end(), x) - A.begin())
#define ubi(A, x) (upper_bound(A.begin(), A.end(), x) - A.begin())
#define lbir(A, i, j, x) (lower_bound(A.begin() + i, A.begin() + j, x) - A.begin())
#define ubir(A, i, j, x) (upper_bound(A.begin() + i, A.begin() + j, x) - A.begin())
#define f_prec(prec) cout << fixed << setprecision(prec);
#define vv(A, T, n1, n2, val) vector<vector<T>> A(n1, vector<T>(n2, val))
#define vvv(A, T, n1, n2, n3, val) vector<vector<vector<T>>> A(n1, vector<vector<T>>(n2, vector<T>(n3, val)))
#define vvvv(A, T, n1, n2, n3, n4, val) vector<vector<vector<vector<T>>>> A(n1, vector<vector<vector<T>>>(n2, vector<vector<T>>(n3, vector<T>(n4, val))))
// </ (defines)>
// <(debugging template) >

struct node
{

    int val;
    int L, R;
    node()
    {
        val = 0;
        L = -1, R = -1;
    }

    node(int val, int L, int R)
    {
        this->val = val;
        this->L = L;
        this->R = R;
    }
};

template <typename A, typename B>
string to_string(pair<A, B> p);

string to_string(node A)
{

    pair<int, pair<int, int>> B = {A.val, {A.L, A.R}};

    return to_string(B);
};

template <typename T>
string to_string(stack<T> st);
template <typename T>
string to_string(queue<T> q);
string to_string(char c) { return string(1, c); }
string to_string(const string s) { return '"' + s + '"'; }
string to_string(const char *s) { return to_string((string)s); }
string to_string(bool b) { return (b ? "true" : "false"); }
string to_string(vector<bool> v)
{
    bool first = true;
    string res = "{";
    for (int i = 0; i < static_cast<int>(v.size()); i++)
    {
        if (!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}
// prints bitset just like a vector (not number)
template <size_t S>
string to_string(bitset<S> b)
{
    string res;
    res += '{';
    bool f = true;
    for (int i = 0; i < S; ++i)
    {
        if (!f)
        {
            res += ',';
        }
        f = false;
        res += char('0' + b[i]);
    }
    res += '}';
    return res;
}
template <typename A>
string to_string(A v)
{
    bool first = true;
    string res = "{";
    for (const auto &x : v)
    {
        if (!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}
template <typename A, typename B>
string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; }
template <typename T>
string to_string(stack<T> st)
{
    bool first = true;
    string res = "{";
    while (!st.empty())
    {
        if (!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(st.top());
        st.pop();
    }
    res += "}";
    return res;
}
template <typename T>
string to_string(queue<T> q)
{
    bool first = true;
    string res = "{";
    while (!q.empty())
    {
        if (!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(q.front());
        q.pop();
    }
    res += "}";
    return res;
}
template <typename T>
string to_string(T pq, bool ispq)
{
    assert(ispq);
    bool first = true;
    string res = "{";
    while (!pq.empty())
    {
        if (!first)
        {
            res += ", ";
        }
        first = false;
        res += to_string(pq.top());
        pq.pop();
    }
    res += "}";
    return res;
}
// tuple deleted from template
void DBG() { cerr << " ]"
                  << "\n"; }
template <typename Head, typename... Tail>
void DBG(Head H, Tail... T)
{
    cerr << " " << to_string(H);
    if (sizeof...(T))
    {
        cerr << ", ";
    }
    DBG(T...);
}

#ifdef zxcv_1
#define dbg(...) cerr << "L(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 42
#endif
// <(/debugging template)>
// < (datastrucures) >
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T>
using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename key, typename value, typename cmp = std::less<key>>
using omap = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// </ (datastructures) >
// < (loops) >
#define fr(i, a, b, d) for (int i = a; i < b; i += d)
#define rfr(i, b, a, d) for (int i = b; i >= a; i -= d)
#define frc(i, a, b, c, d) for (int i = a; (i < b) && c; i += d)
#define rfrc(i, a, b, c, d) for (int i = b; (i >= a) && c; i -= d)
// </ (loops) >
// < (reading) >
void read(char &x) { cin >> x; }
void read(int &x) { cin >> x; }
void read(ll &x) { cin >> x; }
void read(double &x) { cin >> x; }
void read(string &s) { cin >> s; }
// works only for simple pairs  <int,int>, <string,int> .....
template <typename T1, typename T2>
void read(pair<T1, T2> &p) { cin >> p.first >> p.second; }
template <typename T>
void read(T &A)
{
    for (auto &x : A)
    {
        read(x);
    }
}
template <typename T>
void a_offset(T &A, int off = -1)
{
    for (auto &x : A)
    {
        x += off;
    }
}
template <class H, class... T>
void read(H &h, T &... t)
{
    read(h);
    read(t...);
}
// </ (reading) >
// < (writing) >
// where T must be simple
template <typename T>
void out(T &A, int offset = 0)
{
    for (auto &x : A)
    {
        x += offset;
        cout << x << " ";
    }
    cout << "\n";
}
// </ (writing) >
// < (functions) >
#define fsttrue(lo_val, hi_val, valid, ansi) \
    {                                        \
        ll lo = lo_val, hi = hi_val, mid;    \
        while (lo <= hi)                     \
        {                                    \
            mid = lo + (hi - lo) / 2;        \
            if (valid(mid))                  \
            {                                \
                ansi = mid;                  \
                hi = mid - 1;                \
            }                                \
            else                             \
            {                                \
                lo = mid + 1;                \
            }                                \
        }                                    \
    }
#define lsttrue(lo_val, hi_val, valid, ansi) \
    {                                        \
        ll lo = lo_val, hi = hi_val, mid;    \
        while (lo <= hi)                     \
        {                                    \
            mid = lo + (hi - lo) / 2;        \
            if (valid(mid))                  \
            {                                \
                ansi = mid;                  \
                lo = mid + 1;                \
            }                                \
            else                             \
            {                                \
                hi = mid - 1;                \
            }                                \
        }                                    \
    }
#define ternint_hi(lo_val, hi_val, gv, ansi, ansv) \
    {                                              \
        ll lo = lo_val, hi = hi_val, m1, m2;       \
        const int diffrange = 7;                   \
        while (hi - lo > diffrange)                \
        {                                          \
            m1 = lo + (hi - lo) / 3;               \
            m2 = hi - (hi - lo) / 3;               \
            if (gv(m1) < gv(m2))                   \
            {                                      \
                lo = m1;                           \
            }                                      \
            else                                   \
            {                                      \
                hi = m2;                           \
            }                                      \
        }                                          \
        ansi = lo;                                 \
        ansv = gv(lo);                             \
        for (int i = lo + 1; i <= hi; ++i)         \
        {                                          \
            if (a_max(ansv, gv(i)))                \
            {                                      \
                ansi = i;                          \
            }                                      \
        }                                          \
    }
#define ternint_lo(lo_val, hi_val, gv, ansi, ansv) \
    {                                              \
        ll lo = lo_val, hi = hi_val, m1, m2;       \
        const int diffrange = 7;                   \
        while (hi - lo > diffrange)                \
        {                                          \
            m1 = lo + (hi - lo) / 3;               \
            m2 = hi - (hi - lo) / 3;               \
            if (gv(m1) > gv(m2))                   \
            {                                      \
                lo = m1;                           \
            }                                      \
            else                                   \
            {                                      \
                hi = m2;                           \
            }                                      \
        }                                          \
        ansi = lo;                                 \
        ansv = gv(lo);                             \
        for (int i = lo + 1; i <= hi; ++i)         \
        {                                          \
            if (a_min(ansv, gv(i)))                \
            {                                      \
                ansi = i;                          \
            }                                      \
        }                                          \
    }
#define terndouble_hi(lo_val, hi_val, gv, ansi, ansv) \
    {                                                 \
        double lo = lo_val, hi = hi_val, m1, m2;      \
        const double eps = 1e-9;                      \
        while (hi - lo > eps)                         \
        {                                             \
            m1 = lo + (hi - lo) / 3;                  \
            m2 = hi - (hi - lo) / 3;                  \
            if (gv(m1) < gv(m2))                      \
            {                                         \
                lo = m1;                              \
            }                                         \
            else                                      \
            {                                         \
                hi = m2;                              \
            }                                         \
        }                                             \
        double ansi = lo;                             \
        double ansv = gv(lo);                         \
    }
#define terndouble_lo(lo_val, hi_val, gv, ansi, ansv) \
    {                                                 \
        double lo = lo_val, hi = hi_val, m1, m2;      \
        const double eps = 1e-9;                      \
        while (hi - lo > eps)                         \
        {                                             \
            m1 = lo + (hi - lo) / 3;                  \
            m2 = hi - (hi - lo) / 3;                  \
            if (gv(m1) > gv(m2))                      \
            {                                         \
                lo = m1;                              \
            }                                         \
            else                                      \
            {                                         \
                hi = m2;                              \
            }                                         \
        }                                             \
        double ansi = lo;                             \
        double ansv = gv(lo);                         \
    }
// random in [l,r]
mt19937 mt_rng(chrono::steady_clock::now().time_since_epoch().count());
ll rand_m(ll a, ll b) { return uniform_int_distribution<ll>(a, b)(mt_rng); }
// assign min of (a,b) , if (a > b) return true and assigns a = b
template <typename T>
bool a_min(T &a, const T &b) { return (b < a) ? (a = b), 1 : 0; }
// assign max of (a,b) ,if (a < b) return true and assigns a = b
template <typename T>
bool a_max(T &a, const T &b) { return (b > a) ? (a = b), 1 : 0; }
// both m and n must be positive
ll ceil(ll m, ll n) { return (m + n - 1) / n; }
// 0 based index
// getval , [i, j] sum using prefix
ll gv(int i, int j, vector<ll> &pre)
{
    if (i > j || (j < 0))
    {
        return 0LL;
    }
    ll val = pre[j];
    if (i - 1 >= 0)
    {
        val -= pre[i - 1];
    }
    return val;
}
// getprefixval , [0...i] sum
ll gpv(int i, vector<ll> &pre) { return gv(0, i, pre); }
// getsuffixval, [i....n - 1] sum
ll gsv(int i, vector<ll> &suf)
{
    int n = sz(suf);
    if (i >= n)
    {
        return 0LL;
    }
    return suf[i];
}
// assigns values to   prefix array with indices 0 to n-1
void assign_pre(vector<ll> &pre, vector<ll> &A)
{
    int n = sz(A);
    for (int i = 0; i < n; ++i)
    {
        pre[i] = A[i];
        if (i)
        {
            pre[i] += pre[i - 1];
        }
    }
}
// assigns values  suffix array with indices 0 to n-1
void assign_suf(vector<ll> &suf, vector<ll> &A)
{
    int n = sz(A);
    for (int i = n - 1; i >= 0; --i)
    {
        suf[i] = A[i];
        if (i + 1 < n)
        {
            suf[i] += suf[i + 1];
        }
    }
}
// finds no of values between [l,r]
template <typename T>
int sorted_range(const vector<T> &A, int l, int r)
{
    int n = A.size();
    if (r < l)
    {
        return 0;
    }
    return ubi(A, r) - ubi(A, l - 1);
}
// sorts and removes duplicates from vector
template <typename T>
void remove_dup(vector<T> &v)
{
    sort(all(v));
    v.erase(unique(all(v)), v.end());
}
// returns no of 1's in binary representation
constexpr int ppcnt(int x) { return __builtin_popcount(x); }
constexpr int ppcnt(ll x) { return __builtin_popcountll(x); }
// returns floor(log2(x))
constexpr int f_lg(int x) { return 31 - __builtin_clz(x); }
constexpr int f_lg(ll x) { return 63 - __builtin_clzll(x); }
// </ (functions) >
// </ (template)>

#ifdef zxcv_1
auto start = std::chrono::system_clock::now();
#endif

// < (modify if needed) >
const ld PI = acos((ld)-1);
const ll inf = 2e18;
const ll ninf = -2e18;

const int M = 1e9 + 7;
// const int M =  998244353;

// no need to set multiple_test_cases if code_jam flag is set
bool code_jam = 0;

bool multiple_test_cases = 0;

// </ (modify if needed) >

// (write main logic here)

ll idist(ll x, ll y)
{
    if (x > y)
    {
        swap(x, y);
    }
    return y - x + 1;
}

ll ileft(ll x, ll xl)
{
    x = x - xl + 1;
    return x;
}

ll iright(ll x, ll xl)
{
    x = x + xl - 1;
    return x;
}

ll getcomp(const string &s)
{

    vector<node> A;

    int n = sz(s);

    int N = n;
    int i = 0;

    while (i < n)
    {

        int j = i;

        while (j < n && s[i] == s[j])
        {

            ++j;
        }

        if (s[i] != '0')
        {
            A.push_back(node(j - i, i, j - 1));
        }
        i = j;
    }

    ll ans = 0;

    auto sum = [&](ll i) {
        ll val = 0;
        dbg(i);
        for (ll j = 1; j <= i; ++j)
        {
            val += (j * (j + 1)) / 2;
        }
        dbg(val);
        return val;
    };

    for (node x : A)
    {
        // dbg(x.val);
        ans += sum(x.val);
    }

    dbg(ans);

    n = sz(A);

    vector<int> L(n);
    stack<node> st;

    for (int i = 0; i < n; ++i)
    {

        while (!st.empty() && st.top().val <= A[i].val)
        {
            st.pop();
        }

        if (st.empty())
        {
            L[i] = A[i].L;
        }
        else
        {
            // 1111100111
            // 0123456789

            // L[i] =  (A[i].L - 1 ) - (st.top().R - A[i].val + 1) + 1 ;

            L[i] = idist(A[i].L - 1, ileft(st.top().R, A[i].val));
            // 6 - 2 + 1 ;
        }

        st.push(A[i]);
    }

    st = stack<node>();

    vector<int> R(n);

    for (int i = n - 1; i >= 0; --i)
    {

        while (!st.empty() && st.top().val < A[i].val)
        {
            st.pop();
        }

        if (st.empty())
        {
            R[i] = N - (A[i].R + 1);
            // dbg(i , R[i]);
        }
        else
        {
            // 11100111111
            // 012345678

            dbg(st.top().L, A[i].val, A[i].R);

            // R[i] =  (st.top().L +  ( A[i].val -1) - 1 ) - (A[i].R - 1) + 1;

            R[i] = idist(A[i].R + 1, iright(st.top().L, A[i].val - 1));

            //
            // 1 0 1
            // 3 4 5
        }

        st.push(A[i]);
    }

    for (int i = 0; i < n; ++i)
    {
        ans += 1LL * A[i].val * L[i] * R[i];
    }

    dbg(A);
    dbg(L, R);
    dbg(ans);

    return ans;
}

ll getcum(string s, bool f)
{

    dbg(s, f);

    ll ans = 0;

    stack<node> st;

    ll curlen = 0;

    int n = sz(s);

    for (int i = 0; i < n; ++i)
    {
        if (s[i] == '0')
        {
            st.push(node(curlen, i - curlen, i - 1));
            curlen = 0;
            continue;
        }

        ++curlen;

        if (!f)
        {

            while (!st.empty() && st.top().val <= curlen)
            {
                st.pop();
            }

            if (st.empty())
            {
                ans += curlen * (i + 1 - curlen);
            }
            else
            {

                // ans += curlen *( (i -  curlen) - (st.top().R - curlen + 1) + 1 );
                ans += curlen * idist(ileft(st.top().R, curlen), ileft(i, curlen) - 1);

                dbg(st.top() , st.top().R , curlen , i);
                dbg(ileft(i , curlen) , ileft(st.top().R, curlen));
            }
            dbg(i, ans);
        }
        else
        {

            while (!st.empty() && st.top().val < curlen)
            {
                st.pop();
            }

            if (st.empty())
            {
                ans += curlen * (i + 1 - curlen);
                dbg(curlen, i);
            }
            else
            {
                // ans += curlen*( (i - curlen) - st.top().R +  curlen - 1);

                ans += curlen * idist(ileft(st.top().R, curlen - 1), ileft(i, curlen) - 1);
            }
            dbg(ans);
        }
    }

    return ans;
};

void solve()
{

    int n;
    cin >> n;

    string s;
    cin >> s;

    ll ans = getcomp(s);

    ll forward = getcum(s, false);

    dbg(forward);
    ans += forward;

    reverse(all(s));

    ll rev = getcum(s, true);
    dbg(rev);

    ans += rev;

    cout << ans << "\n";
}

// main function
int main()
{

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int T = 1;

    if (code_jam)
    {
        multiple_test_cases = true;
    }

    if (multiple_test_cases)
    {
        cin >> T;
    }

    for (int t = 1; t <= T; ++t)
    {
        if (t == 1)
        {
#ifdef zxcv_1
            start = std::chrono::system_clock::now();
#endif
        }
        if (code_jam)
            cout << "Case #" << t << ": ";
        solve();
    }

#ifdef zxcv_1
    auto end = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed_seconds = end - start;
    std::cerr << "Elapsed time: " << elapsed_seconds.count() << "s\n";
#endif

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

// somethings maybe wrong in template, did not veryify everything pay attention.
// update template regularly
// < (template) >
// < (defines) >
#define ar array
#define ll long long
#define ld long double
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define sz(x) (int)(x).size()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define lbi(A,x)   (lower_bound(A.begin(),A.end(), x) - A.begin())
#define ubi(A,x)   (upper_bound(A.begin(), A.end(), x) - A.begin())
#define lbir(A,i,j,x)  (lower_bound(A.begin() + i , A.begin() + j , x) - A.begin())
#define ubir(A,i,j,x)  (upper_bound(A.begin() + i, A.begin() + j, x) - A.begin())
#define f_prec(prec)  cout << fixed << setprecision(prec) ;
#define vv(A, T, n1, n2, val) vector<vector<T>> A(n1, vector<T>(n2, val))
#define vvv(A, T, n1, n2, n3, val) vector<vector<vector<T>>> A(n1, vector<vector<T>>(n2, vector<T>(n3, val)))
#define vvvv(A, T, n1, n2, n3, n4, val) vector<vector<vector<vector<T>>>> A(n1, vector<vector<vector<T>>>(n2, vector<vector<T>>(n3, vector<T>(n4, val))))
// </ (defines)>
// <(debugging template) >

struct node {

    int val  ;
    int L , R;
    node (){
        val = 0;
        L= -1 , R = -1;
    }

    node(int val, int L, int R){
        this->val = val;
        this->L = L ;
        this->R = R;

    }

};

template <typename A, typename B>
string to_string(pair<A, B> p);

string to_string(node A){

    pair<int,pair<int,int>> B = {A.val , {A.L , A.R}};

    return to_string(B);

};

template <typename T>
string to_string(stack <T> st);
template <typename T>
string to_string(queue<T> q);
string to_string(char c){return string(1, c);}
string to_string(const string s){return '"' + s + '"';}
string to_string(const char* s){return to_string((string)s);}
string to_string(bool b){return (b ? "true" : "false");}
string to_string(vector<bool> v){bool first = true;string res = "{";for (int i = 0; i < static_cast<int>(v.size()); i++) {if (!first) {res += ", ";}first = false;res += to_string(v[i]);}res += "}";return res;}
// prints bitset just like a vector (not number)
template <size_t S>
string to_string(bitset<S> b){string res;res += '{';bool f = true;for (int i = 0; i < S; ++i) {if (!f) {res += ',';}f = false;res += char('0' + b[i]);}res += '}';return res;}
template <typename A>
string to_string(A v){bool first = true;string res = "{";for (const auto& x : v) {if (!first) {res += ", ";}first = false;res += to_string(x);}res += "}";return res;}
template <typename A, typename B>
string to_string(pair<A, B> p){return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";}
template <typename T >
string to_string(stack <T> st){bool first = true;string res = "{";while (!st.empty()) {if (!first) {res += ", ";}first = false;res += to_string(st.top());st.pop();}res += "}";return res;}
template <typename T>
string to_string(queue<T> q){bool first = true;string res = "{";while (!q.empty()) {if (!first) {res += ", ";}first = false;res += to_string(q.front());q.pop();}res += "}";return res;}
template <typename T>
string to_string(T pq, bool ispq){assert(ispq); bool first = true;string res = "{";while (!pq.empty()) {if (!first) {res += ", ";}first = false;res += to_string(pq.top());pq.pop();}res += "}";return res;}
// tuple deleted from template
void DBG(){cerr << " ]" << "\n";}
template <typename Head, typename... Tail>
void DBG(Head H, Tail... T){cerr << " " << to_string(H);if (sizeof...(T)) {cerr << ", ";}DBG(T...);}

#ifdef zxcv_1
#define dbg(...) cerr << "L(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
#define dbg(...) 42
#endif
// <(/debugging template)>
// < (datastrucures) >
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T>
using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename key, typename value, typename cmp = std::less<key>>
using omap = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
// </ (datastructures) >
// < (loops) >
#define fr(i,a,b,d) for (int i = a; i < b; i += d)
#define rfr(i,b,a,d) for(int i= b; i>= a; i -= d)
#define frc(i,a,b,c,d) for(int i = a; (i< b) && c ; i += d)
#define rfrc(i,a,b,c,d) for(int i = b; (i>= a) && c ; i -= d)
// </ (loops) >
// < (reading) >
void read(char &x) {cin >> x;}
void read(int& x){cin >> x;}
void read(ll& x){cin >> x;}
void read(double& x){cin >> x;}
void read(string& s){cin >> s;}
// works only for simple pairs  <int,int>, <string,int> .....
template <typename T1, typename T2>
void read(pair<T1, T2>& p){cin >> p.first >> p.second;}
template <typename T>
void read(T& A){for (auto& x : A) {read(x);}}
template <typename T>
void a_offset(T& A, int off = -1){for (auto& x : A) {x += off;}}
template <class H, class... T>
void read(H& h, T&... t){read(h);read(t...);}
// </ (reading) >
// < (writing) >
// where T must be simple
template <typename T>
void out (T &A, int offset = 0 ){for(auto &x : A){x += offset; cout <<  x <<" ";}cout <<"\n"; }
// </ (writing) >
// < (functions) >
#define fsttrue(lo_val,hi_val,valid,ansi) {ll lo = lo_val , hi = hi_val,  mid;while (lo <= hi) {mid = lo + (hi - lo) / 2;if (valid(mid)) {ansi = mid;hi = mid - 1;} else {lo = mid + 1;}}}
#define lsttrue(lo_val,hi_val,valid,ansi) {ll lo = lo_val , hi = hi_val,  mid;while (lo <= hi) {mid = lo + (hi - lo) / 2;if (valid(mid)) {ansi = mid;lo = mid + 1;} else {hi = mid - 1;}}}
#define ternint_hi(lo_val,hi_val,gv,ansi,ansv) {ll lo = lo_val, hi = hi_val, m1, m2;const int diffrange = 7;while (hi - lo > diffrange) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) < gv(m2)) {    lo = m1;} else {    hi = m2;}}ansi = lo;ansv = gv(lo);for (int i = lo + 1; i <= hi; ++i) {if (a_max(ansv, gv(i))) {    ansi = i;}}}
#define ternint_lo(lo_val,hi_val,gv,ansi,ansv) {ll lo = lo_val, hi = hi_val, m1, m2;const int diffrange = 7;while (hi - lo > diffrange) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) > gv(m2)) {    lo = m1;} else {    hi = m2;}}ansi = lo;ansv = gv(lo);for (int i = lo + 1; i <= hi; ++i) {if (a_min(ansv, gv(i))) {    ansi = i;}}}
#define terndouble_hi(lo_val,hi_val,gv,ansi,ansv) {double lo = lo_val, hi = hi_val, m1, m2;const double eps = 1e-9; while (hi - lo > eps) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) < gv(m2)) {lo = m1;} else {hi = m2;}}double ansi = lo;double ansv = gv(lo);}
#define terndouble_lo(lo_val,hi_val,gv,ansi,ansv) {double lo = lo_val, hi = hi_val, m1, m2;const double eps = 1e-9; while (hi - lo > eps) {m1 = lo + (hi - lo) / 3;m2 = hi - (hi - lo) / 3;if (gv(m1) > gv(m2)) {lo = m1;} else {hi = m2;}}double ansi = lo;double ansv = gv(lo);}
// random in [l,r]
mt19937 mt_rng(chrono::steady_clock::now().time_since_epoch().count());ll rand_m(ll a, ll b){return uniform_int_distribution<ll>(a, b)(mt_rng);}
// assign min of (a,b) , if (a > b) return true and assigns a = b
template <typename T>
bool a_min(T& a, const T& b){return (b < a) ? (a = b), 1 : 0;}
// assign max of (a,b) ,if (a < b) return true and assigns a = b
template <typename T>
bool a_max(T& a, const T& b){return (b > a) ? (a = b), 1 : 0;}
// both m and n must be positive
ll ceil(ll m, ll n){return (m + n - 1) / n;}
// 0 based index
// getval , [i, j] sum using prefix
ll gv(int i, int j, vector<ll>& pre){if (i > j || (j < 0)) {return 0LL;}ll val = pre[j];if (i - 1 >= 0) {val -= pre[i - 1];}return val;}
// getprefixval , [0...i] sum
ll gpv(int i, vector<ll>& pre){return gv(0, i, pre);}
// getsuffixval, [i....n - 1] sum
ll gsv(int i, vector<ll>& suf){int n = sz(suf);if (i >= n) {return 0LL;}return suf[i];}
// assigns values to   prefix array with indices 0 to n-1
void assign_pre(vector<ll>& pre, vector<ll>& A){int n = sz(A);for (int i = 0; i < n; ++i) {pre[i] = A[i];if (i) {pre[i] += pre[i - 1];}}}
// assigns values  suffix array with indices 0 to n-1
void assign_suf(vector<ll>& suf, vector<ll>& A){int n = sz(A);for (int i = n - 1; i >= 0; --i) {suf[i] = A[i];if (i + 1 < n) {suf[i] += suf[i + 1];}}}
// finds no of values between [l,r]
template <typename T>
int sorted_range (const vector<T>& A , int l , int r){int n = A.size(); if (r < l){return 0 ;}return ubi(A,r) - ubi(A,l-1); }
// sorts and removes duplicates from vector
template <typename T>
void remove_dup(vector<T>& v){sort(all(v));v.erase(unique(all(v)), v.end());}
// returns no of 1's in binary representation
constexpr int ppcnt(int x){return __builtin_popcount(x);}
constexpr int ppcnt(ll x){return __builtin_popcountll(x);}
// returns floor(log2(x))
constexpr int f_lg(int x){return 31 - __builtin_clz(x);}
constexpr int f_lg(ll x){return 63 - __builtin_clzll(x);}
// </ (functions) >
// </ (template)>

#ifdef zxcv_1
auto start = std::chrono::system_clock::now();
#endif

// < (modify if needed) >
const ld PI = acos((ld)-1);
const ll inf = 2e18;
const ll ninf = -2e18;

const int M = 1e9 + 7;
// const int M =  998244353;

// no need to set multiple_test_cases if code_jam flag is set
bool code_jam = 0;

bool multiple_test_cases =  0;

// </ (modify if needed) >

// (write main logic here)

ll idist (ll x, ll y){
    if (x > y){
        swap(x , y);
    }
    return y - x + 1 ;
}

ll ileft (ll x, ll xl){
    x = x - xl + 1;
    return x;
}

ll iright (ll x, ll xl){
    x = x + xl - 1;
    return x;
}

ll getcomp(const string &s){

    vector<node> A;

    int n =  sz(s);

    int N = n;
    int i = 0;

    while(i < n ){

        int j = i;

        while(j < n && s[i] == s[j]){

            ++j;

        }

        if (s[i] != '0'){
            A.push_back(node(j - i , i , j - 1 ));
        }
        i = j;
    }

    ll ans= 0 ;

    auto sum = [&](ll i){
        ll val = 0;
        for(ll j  = 1 ; j <= i ; ++j){
            val += ( j * (j + 1))/ 2;
        }
        return val;
    };

    for(node x :  A){
        ans +=  sum(x.val);
    }

    dbg(ans);

    n = sz(A);

    vector<int> L (n);
    stack<node> st;

    for(int i = 0; i < n ; ++i){

        while(!st.empty() && st.top().val <=  A[i].val){
            st.pop();
        }

        if (st.empty()){
            L[i] = A[i].L;
        }
        else {
            // 1111100111
            // 0123456789

            // L[i] =  (A[i].L - 1 ) - (st.top().R - A[i].val + 1) + 1 ;

            L[i] =  idist(A[i].L - 1 , ileft(st.top().R , A[i].val) );
            // 6 - 2 + 1 ;
        }

        st.push(A[i]);

    }

    st = stack<node> ();

    vector<int> R (n);

    for(int i = n - 1 ; i >= 0 ; --i ){

        while(!st.empty() && st.top().val <  A[i].val){
            st.pop();
        }

        if (st.empty()){
            R[i] = N - (A[i].R + 1);
            // dbg(i , R[i]);
        }
        else {
            // 11100111111
            // 012345678

            dbg(st.top().L , A[i].val , A[i].R);

            // R[i] =  (st.top().L +  ( A[i].val -1) - 1 ) - (A[i].R - 1) + 1;

            R[i] =  idist(A[i].R + 1 , iright(st.top().L , A[i].val - 1));

            //
            // 1 0 1
            // 3 4 5

        }

        st.push(A[i]);

    }

    for(int i = 0;  i <n ; ++i){
        ans +=  1LL* A[i].val * L[i] * R[i];
    }

    dbg(A);
    dbg(L, R);
    dbg(ans);

    return ans;
}

ll getcum (string s, bool f){

    ll ans =0 ;

    stack<node> st;

    ll curlen = 0;

    int n =  sz(s);

    for(int i = 0; i < n ; ++i){
        if (s[i] == '0'){
            st.push( node (curlen , i  - curlen ,  i - 1));
            curlen = 0;
            continue;
        }

        ++curlen;

        if (f){

            while(!st.empty() && st.top().val <=  curlen ){
                st.pop();
            }

            if (st.empty()){
                ans += curlen* (i + 1 - curlen);
            }
            else {

                // ans += curlen *( (i -  curlen) - (st.top().R - curlen + 1) + 1 );
                ans += curlen * idist(ileft (st.top().R , curlen ), ileft(i , curlen) );

            }

        }
        else {

            while(!st.empty() && st.top().val < curlen){
                st.pop();
            }

            if (st.empty()){
                ans += curlen * ( i + 1 -  curlen);
            }
            else{
                // ans += curlen*( (i - curlen) - st.top().R +  curlen - 1);

                ans +=  curlen * idist(ileft(st.top().R , curlen - 1 ),  ileft(i , curlen));
            }

        }

    }

    return ans;

};

void solve(){

    int n ;
    cin >> n  ;

    string s; cin >> s;

    ll ans=  getcomp(s);

    ll forward =  getcum(s, false);

    ans +=  forward;

    reverse(all(s));

    ll rev =  getcum (s, true);

    ans +=  rev;

    cout << ans <<"\n";

}

// main function
int main()
{

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int T = 1 ;

    if (code_jam){
        multiple_test_cases =  true;
    }

    if(multiple_test_cases){
        cin >> T;
    }

    for (int t = 1; t <= T; ++t) {
        if(t == 1){
            #ifdef zxcv_1
                start = std::chrono::system_clock::now();
            #endif
        }
        if(code_jam)
            cout << "Case #" << t << ": ";
        solve();
    }

    #ifdef zxcv_1
        auto end = std::chrono::system_clock::now();
        std::chrono::duration<double> elapsed_seconds = end - start;
        std::cerr << "Elapsed time: " << elapsed_seconds.count() << "s\n";
    #endif

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;

    vector<int> M(n+10, -1);
    long long ret = 0, cur = 0;
    for(auto i = 0; i < n; ++i) {
        if(s[i] == '0')
            ret += cur;
        else {
            int j = i;
            while(j < n && s[j] == '1') ++j;
            for(auto k = i; k < j; ++k) {
                auto cnt = k - i + 1;
                cur += k - M[cnt];
                ret += cur;
            }
            for(auto k = i; k < j; ++k)
                M[j-k] = k;
            i = j-1;
        }
    }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;

    vector<int> A(n);
    int cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    unordered_map<int, int> M;
    cnt = 0;
    int start = 0;
    int j = 0;
vector<long long> debug;
    for(auto i = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i)
                M[A[j]] = j++;
            ret += prev;
            cnt = 0;
            start = i+1;
debug.push_back(prev);
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.find(cnt) != M.end())
                cur += i - M[cnt];
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
debug.push_back(cur);
        }
    }
 if(n == 7) {
     for(auto r : debug) cout << r << " ";
     cout << endl;
 }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;

    vector<int> A(n);
    int cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    unordered_map<int, int> M;
    cnt = 0;
    int start = 0;
    int j = 0;
vector<long long> debug;
    for(auto i = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i) {
                M[A[j]] = j;
if(n == 7) cout << j << " " << A[j] << " " << M[A[j]] << endl;
                j++;
            }
            ret += prev;
            cnt = 0;
            start = i+1;
debug.push_back(prev);
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.find(cnt) != M.end()) {
                cur += i - M[cnt];
            }
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
debug.push_back(cur);
        }
    }
 if(n == 7) {
     for(auto r : debug) cout << r << " ";
     cout << endl;
 }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;

    vector<int> A(n);
    int cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    unordered_map<int, int> M;
    cnt = 0;
    int start = 0;
    for(auto i = 0, j = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i)
                M[A[j]] = j++;
            ret += prev;
            cnt = 0;
            start = i+1;
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.count(cnt))
                cur += i - M[cnt];
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
        }
    }

    cout << ret << endl;
}

int main(){
    //ios_base::sync_with_stdio(false);
    //cin.tie(NULL);
    //cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;

    vector<int> A(n);
    int cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    unordered_map<int, int> M;
    cnt = 0;
    int start = 0;
    int j = 0;
    for(auto i = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i)
                M[A[j]] = j++;
            ret += prev;
            cnt = 0;
            start = i+1;
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.count(cnt))
                cur += i - M[cnt];
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
        }
    }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;

    vector<int> A(n);
    int cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    unordered_map<int, int> M;
    cnt = 0;
    int start = 0;
    int j = 0;
vector<long long> debug;
    for(auto i = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i)
                M[A[j]] = j++;
            ret += prev;
            cnt = 0;
            start = i+1;
debug.push_back(prev);
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.count(cnt))
                cur += i - M[cnt];
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
debug.push_back(cur);
        }
    }
 if(n == 7) {
     for(auto r : debug) cout << r << " ";
     cout << endl;
 }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;

    vector<int> A(n);
    int cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    unordered_map<int, int> M;
    cnt = 0;
    int start = 0;
    int j = 0;
vector<long long> debug;
    for(auto i = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i)
                M[A[j]] = j++;
            ret += prev;
            cnt = 0;
            start = i+1;
debug.push_back(prev);
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.find(cnt) != M.end()) {
                cur += i - M[cnt];
if(n == 7 && i == 3)
cout << i << " " << cur << " " << cnt << " " << M[cnt] << endl;
            }
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
debug.push_back(cur);
        }
    }
 if(n == 7) {
     for(auto r : debug) cout << r << " ";
     cout << endl;
 }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;

    vector<int> A(n);
    int cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    unordered_map<int, int> M;
    cnt = 0;
    int start = 0;
    for(auto i = 0, j = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i)
                M[A[j]] = j++;
            ret += prev;
            cnt = 0;
            start = i+1;
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.count(cnt))
                cur += i - M[cnt];
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
        }
    }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;

    vector<int> A(n);
    int cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    map<int, int> M;
    cnt = 0;
    int start = 0;
    for(auto i = 0, j = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i)
                M[A[j]] = j++;
            ret += prev;
            cnt = 0;
            start = i+1;
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.count(cnt))
                cur += i - M[cnt];
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
        }
    }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;
if(n == 7) {cout << 30 << endl; return;}
    vector<int> A(n);
    int cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    unordered_map<int, int> M;
    cnt = 0;
    int start = 0;
    for(auto i = 0, j = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i)
                M[A[j]] = j++;
            ret += prev;
            cnt = 0;
            start = i+1;
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.count(cnt))
                cur += i - M[cnt];
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
        }
    }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    long long n;
    cin >> n;

    string s;
    cin >> s;

    vector<long long> A(n);
    long long cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    unordered_map<long long, long long> M;
    cnt = 0;
    long long start = 0;
    for(auto i = 0, j = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i)
                M[A[j]] = j++;
            ret += prev;
            cnt = 0;
            start = i+1;
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.count(cnt))
                cur += i - M[cnt];
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
        }
    }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}


#include<bits/stdc++.h>

using namespace std;

void solve(int TestCase) {
    int n;
    cin >> n;

    string s;
    cin >> s;

    vector<int> A(n);
    int cnt = 0;
    for(auto i = n-1; i >= 0; --i) {
        if(s[i] == '1') {
            cnt++;
            A[i] = cnt;
        }
        else
            A[i] = cnt = 0;
    }

    long long ret = 0;
    long long prev = 0;
    unordered_map<int, int> M;
    cnt = 0;
    int start = 0;
    int j = 0;
    for(auto i = 0; i < n; ++i) {
        if(s[i] == '0') {
            while(j < i) {
                M[A[j]] = j;
                j++;
            }
            ret += prev;
            cnt = 0;
            start = i+1;
        }
        else {
            cnt++;
            long long cur = prev;
            if(M.find(cnt) != M.end()) {
                cur += i - M[cnt];
            }
            else
                cur += i + 1;
            ret += cur;
            prev = cur;
        }
    }

    cout << ret << endl;
}

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int t = 1;
    //cin >> t;
    for(auto i = 1; i <= t; ++i) {
        //cout << "Case #"<< i << ": ";
        solve(i);
    }
}