#include <stdio.h>
//#include <conio.h> /////////////////////////////////////////////////////////////////////////////////////////////

signed long dodatnie=0, ujemne=0, krotnosci[2000001], n, UCB[501], GRANICA, krot_mniejsze[130001], krot_wieksze[130001];
signed long mniejsze[130001], wieksze[130001], SUMA, ind_dol, ind_gora, indeksy[130001], pom1, ind_srod, licz_ind, ind_znal;
signed long wartosc_srodk, wartosc_dol, wartosc_gora, Start_ind_gora;
long long WYNIK, POM_WYNIK, krotnosc_srodk, krotnosc_dol, krotnosc_gora;
char stop,stopstop;



int SZUKAJ_wieksze(long pocz, long kon)
{
long srod;
if (pocz>kon) return 0;
if (pocz==kon)   
	{
	 if (wieksze[pocz]==-SUMA)   ind_znal=pocz;
	 return 0;
	}
srod = (pocz+kon)/2;
if (wieksze[srod] == -SUMA)   ind_znal=srod;
else if (wieksze[srod] > -SUMA)   SZUKAJ_wieksze(pocz, srod-1);
else SZUKAJ_wieksze(srod+1,kon);

return 0;
}


int SZUKAJ_mniejsze(long pocz, long kon)
{
long srod;
if (pocz>kon) return 0;
if (pocz==kon)   
	{
	 if (mniejsze[pocz]==-SUMA)   ind_znal=pocz;
	 return 0;
	}
srod = (pocz+kon)/2;
if (mniejsze[srod] == -SUMA)   ind_znal=srod;
else if (mniejsze[srod] > -SUMA)   SZUKAJ_mniejsze(pocz, srod-1);
else SZUKAJ_mniejsze(srod+1,kon);

return 0;
}





int SORT_mniejsze(int pocz,int kon) //Przepisane z Cormena
{
signed long sx,sq,si,sj,pom;
if(pocz<kon)
    {
     sx = mniejsze[kon];
     si=pocz-1;
     for(sj=pocz;sj<=kon-1;sj++)
        {
         if (mniejsze[sj]<sx) 
            {
             si++;
             pom=mniejsze[si]; mniejsze[si]=mniejsze[sj]; mniejsze[sj]=pom;
            }
        }
     pom=mniejsze[si+1]; mniejsze[si+1]=mniejsze[kon]; mniejsze[kon]=pom;
     sq=si+1;
     SORT_mniejsze(pocz,sq-1);
     SORT_mniejsze(sq+1,kon);
    }
return 0;
}



int SORT_wieksze(int pocz,int kon) //Przepisane z Cormena
{
signed long sx,sq,si,sj,pom;
if(pocz<kon)
    {
     sx = wieksze[kon];
     si=pocz-1;
     for(sj=pocz;sj<=kon-1;sj++)
        {
         if (wieksze[sj]<sx) 
            {
             si++;
             pom=wieksze[si]; wieksze[si]=wieksze[sj]; wieksze[sj]=pom;
            }
        }
     pom=wieksze[si+1]; wieksze[si+1]=wieksze[kon]; wieksze[kon]=pom;
     sq=si+1;
     SORT_wieksze(pocz,sq-1);
     SORT_wieksze(sq+1,kon);
    }
return 0;
}





int main()
{
for (int ii=0; ii<=2000000; ii++) krotnosci[ii]=0;
for (int ii=0; ii<=130000; ii++) { krot_mniejsze[ii]=0; krot_wieksze[ii]=0; }
mniejsze[0]=0;   wieksze[0]=0;

scanf("%ld",&n);
for (int ii=1; ii<=n; ii++)   scanf("%ld",&UCB[ii]);


// od -MLN do +MLN tablicuję (czyli sortowanie w czasie liniowym), a te, które wykraczają poza ten zakres wchodzą do dwóch tablic: mniejsze i wieksze
// Na bieżąco podliczam dodatnie i ujemne, aby móc pójść od strony, która zajmnie mniej czasu.
// Przy tym podliczaniu liczby spoza zakresu standardowo, ale liczby w zakresie - tylko pierwsze pojawienie się.

GRANICA = 1000000;
//GRANICA = 3;  //////////////////////////////////////////////////////////////////////////////

for (int ii=1; ii<=n; ii++)
	{
	 SUMA=0;
	 for (int jj=ii; jj<=n; jj++)
	 	{
	 	 SUMA += UCB[jj];
	 	 if (SUMA < 0)
	 	 	{
	 	 	 if (SUMA < -GRANICA) 
	 	 	 	{
	 	 	 	 mniejsze[0]++;
	 	 	 	 mniejsze[mniejsze[0]] = SUMA;
	 	 	 	}
	 	 	 else
	 	 	 	{
	 	 	 	 if (krotnosci[SUMA+GRANICA]==0) ujemne++;
	 	 	 	 krotnosci[SUMA+GRANICA]++;
	 	 	 	}
	 	 	}
	 	 else
	 	 	{
	 	 	 if (SUMA > GRANICA)
	 	 	 	{
	 	 	 	 wieksze[0]++;
	 	 	 	 wieksze[wieksze[0]] = SUMA;
	 	 	 	}
	 	 	 else
	 	 	 	{
	 	 	 	 if (krotnosci[SUMA+GRANICA]==0) dodatnie++;
	 	 	 	 krotnosci[SUMA+GRANICA]++;
	 	 	 	}
	 	 	}
	 	}
	}

SORT_mniejsze(1,mniejsze[0]);
SORT_wieksze(1,wieksze[0]);

// Dodatnie "krotności" mniejszych i większych
ind_dol=1;   ind_gora=1; 
if (mniejsze[0]>0)  {  krot_mniejsze[1]=1;  ujemne++;  }

for (ind_gora=2; ind_gora <= mniejsze[0]; ind_gora++)
	{
	 if (mniejsze[ind_gora-1] == mniejsze[ind_gora])    krot_mniejsze[ind_dol]++;
	 else 
	 	{
	 	 ind_dol++;
	 	 krot_mniejsze[ind_dol]++;
	 	 ujemne++;
	 	 if (ind_dol != ind_gora)   mniejsze[ind_dol] = mniejsze[ind_gora];
	 	}
	}
if (mniejsze[0]>0)    mniejsze[0] = ind_dol;

ind_dol=1;   ind_gora=1;
if (wieksze[0]>0)   { krot_wieksze[1]=1;   dodatnie++;  }

for (ind_gora=2; ind_gora <= wieksze[0]; ind_gora++)
	{
	 if (wieksze[ind_gora-1] == wieksze[ind_gora] )    krot_wieksze[ind_dol]++;
	 else
	 	{
	 	 ind_dol++;
	 	 krot_wieksze[ind_dol]++;
	 	 dodatnie++;
	 	 if (ind_dol != ind_gora)   wieksze[ind_dol] = wieksze[ind_gora];
	 	}
	}
if (wieksze[0]>0)   wieksze[0] = ind_dol;

/*
printf("Mniejsze: \n");
for (int ii=1; ii<=mniejsze[0]; ii++)   printf("krot[%ld]=%ld\n", mniejsze[ii], krot_mniejsze[ii]);
printf("Krotnosci:\n");
for (signed int ii=-10; ii<=10; ii++)   printf("krot[%d]=%ld\n",ii,krotnosci[GRANICA+ii]);
printf("Wieksze:\n");
for (int ii=1; ii<=wieksze[0]; ii++)   printf("krot[%ld]=%ld\n", wieksze[ii], krot_wieksze[ii]);
printf("Ujemne: %ld\n",ujemne);
printf("Dodatnie: %ld\n",dodatnie);
*/

// Uzupełnienie niezerowych indeksów z głównej tablicy:
licz_ind=0;
for (int ii=0; ii<=2000000; ii++)    if (krotnosci[ii] != 0 )
	{
	 licz_ind++;
	 indeksy[licz_ind]=ii;
	}

for (int ii=1; ii<=licz_ind; ii++)

// Teraz powinienem iść od tej strony (dodatniej lub ujemnej) z której było mniej.

Start_ind_gora = mniejsze[0] + licz_ind + wieksze[0] + 1; 

WYNIK = 0;
//if (ujemne < dodatnie)
if (1 == 1)
	{ // Idziemy od strony ujemnej
	 ind_dol=0; 
	 stop = 0;
	 while (!stop)
	 	{
	 	 ind_dol++;
	 	 if (ind_dol<=mniejsze[0])   
		 	{
		 	 wartosc_dol = mniejsze[ind_dol];
		 	 krotnosc_dol = krot_mniejsze[ind_dol];
		 	 SUMA = wartosc_dol; // Mała suma - dwóch pierwszych
			}
		 else  // Jeśli jest już w krotnosciach
		 	{
		 	 wartosc_dol = indeksy[ ind_dol-mniejsze[0] ] - GRANICA;
		 	 krotnosc_dol = krotnosci[ indeksy[ ind_dol-mniejsze[0] ] ];
		 	 SUMA = wartosc_dol;
		 	}
	 	 
	 	 // Teraz drugim indeksem idę od góry w dół i po zsumowaniu patrzę, czy da się złożyć.
	 	 ind_gora = Start_ind_gora;
	 	 stopstop=0;
	 	 while (!stopstop) // Pętla dla drugiego indeksu
	 	 	{
	 	 	 ind_gora--;
	 	 	 // Dodaję do tego, co już mam
	 	 	 if (ind_gora > mniejsze[0] + licz_ind)
	 	 	 	{
	 	 	 	 wartosc_gora = wieksze[ind_gora - mniejsze[0] - licz_ind];
	 	 	 	 krotnosc_gora = krot_wieksze[ind_gora - mniejsze[0] - licz_ind];
	 	 	 	 SUMA += wartosc_gora;
	 	 	 	}
	 	 	 else 
	 	 	 	{ // Jest w krotnościach - niżej zejść nie może
	 	 	 	 wartosc_gora = indeksy[ ind_gora-mniejsze[0] ] - GRANICA;
	 	 	 	 krotnosc_gora = krotnosci[ indeksy[ ind_gora-mniejsze[0] ] ];
	 	 	 	 SUMA += wartosc_gora;
	 	 	 	}
	 	 	 
//	 	 	 printf("(ind=%ld) wart=%ld (krot=%ld)   +   (ind=%ld) wart=%ld (krot=%ld)   => Szukam wart=%ld\n",ind_dol,wartosc_dol,krotnosc_dol,  ind_gora,wartosc_gora,krotnosc_gora, -SUMA );
//	 	 	 getch(); //////////////////////////////////////////////////////////////////////////////////////////////////
	 	 	 
	 	 	 // Teraz szukam, czy jest gdzieś (-SUMA) i czy pomiędzy dołem i górą?
	 	 	 if ((-SUMA >= wartosc_dol) && (-SUMA <= wartosc_gora))
	 	 	 	{
	 	 	 	 if ((-SUMA <= GRANICA) && (-SUMA >= -GRANICA))
	 	 	 	 	{ // Środkowa wartość będzie w krotnościach
	 	 	 	 	 if ( krotnosci[-SUMA+GRANICA] > 0 )
	 	 	 	 	 	{ // ZNALEZIONY!!! :) Dodajemy coś do wyniku
	 	 	 	 	 	 // Możemy mieć trzy przypadki szczególne: -wszystkie te same wartości   -takie same dwie pierwsze     -takie same dwie ostatnie
	 	 	 	 	 	 // W pozostałych przypadkach po prostu mnożę krotności
	 	 	 	 	 	 krotnosc_srodk = krotnosci[-SUMA+GRANICA];
	 	 	 	 	 	 wartosc_srodk = -SUMA;
//	 	 	 	 	 	 printf("a) ZNALAZŁEM! wartosci: %ld %ld %ld,  krotnosci: %lld %lld %lld\n",wartosc_dol,wartosc_srodk,wartosc_gora, krotnosc_dol,krotnosc_srodk,krotnosc_gora );
	 	 	 	 	 	 if ((wartosc_dol==wartosc_srodk)&&(wartosc_srodk==wartosc_gora))
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += (krotnosc_dol*(krotnosc_dol-1)*(krotnosc_dol-2)) / 6;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",(krotnosc_dol*(krotnosc_dol-1)*(krotnosc_dol-2)) / 6);
	 	 	 	 	 	 	}
	 	 	 	 	 	 else if (wartosc_dol == wartosc_srodk)
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += ((krotnosc_dol*(krotnosc_dol-1))/2) * krotnosc_gora;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",((krotnosc_dol*(krotnosc_dol-1))/2) * krotnosc_gora);
	 	 	 	 	 	 	}
	 	 	 	 	 	 else if (wartosc_srodk == wartosc_gora)
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += ((krotnosc_srodk*(krotnosc_srodk-1))/2) * krotnosc_dol;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",((krotnosc_srodk*(krotnosc_srodk-1))/2) * krotnosc_dol);
	 	 	 	 	 	 	}
	 	 	 	 	 	 else // Trzy różne wartości
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += krotnosc_dol*krotnosc_srodk*krotnosc_gora;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",krotnosc_dol*krotnosc_srodk*krotnosc_gora);
	 	 	 	 	 	 	}
	 	 	 	 	 	}
	 	 	 	 	}
	 	 	 	 else if (-SUMA > GRANICA)
	 	 	 	 	{// Środkowej wartości szukamy w większych
	 	 	 	 	 
	 	 	 	 	 // SZUKANIE POWINNO BYĆ BINARNE!!!    // Jak zrealizować szukanie w jednoelementowym???
	 	 	 	 	 // Wartość, której szukam to -SUMA, więc tego parametru nie muszę przekazywać
	 	 	 	 	 ind_znal = 0;
					 SZUKAJ_wieksze( 1 , ind_gora - mniejsze[0] - licz_ind );
	 	 	 	 	 
	 	 	 	 	 if (ind_znal > 0)
	 	 	 	 	 	{ // ZNALEZIONO!!! :)
	 	 	 	 	 	 // Dodajemy coś do wyniku... Też 3 przypadki szczególne
	 	 	 	 	 	 krotnosc_srodk = krot_wieksze[ind_znal];
	 	 	 	 	 	 wartosc_srodk = -SUMA;
	 	 	 	 	 	 
//	 	 	 	 	 	 printf("b) ZNALAZŁEM! wartosci: %ld %ld %ld,  krotnosci: %lld %lld %lld\n",wartosc_dol,wartosc_srodk,wartosc_gora, krotnosc_dol,krotnosc_srodk,krotnosc_gora );
	 	 	 	 	 	 
	 	 	 	 	 	 if ((wartosc_dol==wartosc_srodk)&&(wartosc_srodk==wartosc_gora))
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += (krotnosc_dol*(krotnosc_dol-1)*(krotnosc_dol-2)) / 6;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",(krotnosc_dol*(krotnosc_dol-1)*(krotnosc_dol-2)) / 6);
	 	 	 	 	 	 	}
	 	 	 	 	 	 else if (wartosc_dol == wartosc_srodk)
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += ((krotnosc_dol*(krotnosc_dol-1))/2) * krotnosc_gora;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",((krotnosc_dol*(krotnosc_dol-1))/2) * krotnosc_gora);
	 	 	 	 	 	 	}
	 	 	 	 	 	 else if (wartosc_srodk == wartosc_gora)
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += ((krotnosc_srodk*(krotnosc_srodk-1))/2) * krotnosc_dol;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",((krotnosc_srodk*(krotnosc_srodk-1))/2) * krotnosc_dol);
	 	 	 	 	 	 	}
	 	 	 	 	 	 else // Trzy różne wartości
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += krotnosc_dol*krotnosc_srodk*krotnosc_gora;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",krotnosc_dol*krotnosc_srodk*krotnosc_gora);
	 	 	 	 	 	 	}
	 	 	 	 	 	}
	 	 	 	 	}
	 	 	 	 else
	 	 	 	 	{// Środkowej wartości szukamy w mniejszych
	 	 	 	 	 ind_znal = 0;
					 SZUKAJ_mniejsze( ind_dol , mniejsze[0] );
	 	 	 	 	 
	 	 	 	 	 if (ind_znal > 0)
	 	 	 	 	 	{ // ZNALEZIONO!!! :)
	 	 	 	 	 	 // Dodajemy coś do wyniku... Też 3 przypadki szczególne
	 	 	 	 	 	 krotnosc_srodk = krot_mniejsze[ind_znal];
	 	 	 	 	 	 wartosc_srodk = -SUMA;
	 	 	 	 	 	 
//	 	 	 	 	 	 printf("c)ZNALAZŁEM! wartosci: %ld %ld %ld,  krotnosci: %lld %lld %lld\n",wartosc_dol,wartosc_srodk,wartosc_gora, krotnosc_dol,krotnosc_srodk,krotnosc_gora );
	 	 	 	 	 	 
	 	 	 	 	 	 if ((wartosc_dol==wartosc_srodk)&&(wartosc_srodk==wartosc_gora))
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += (krotnosc_dol*(krotnosc_dol-1)*(krotnosc_dol-2)) / 6;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",(krotnosc_dol*(krotnosc_dol-1)*(krotnosc_dol-2)) / 6);
	 	 	 	 	 	 	}
	 	 	 	 	 	 else if (wartosc_dol == wartosc_srodk)
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += ((krotnosc_dol*(krotnosc_dol-1))/2) * krotnosc_gora;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",((krotnosc_dol*(krotnosc_dol-1))/2) * krotnosc_gora);
	 	 	 	 	 	 	}
	 	 	 	 	 	 else if (wartosc_srodk == wartosc_gora)
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += ((krotnosc_srodk*(krotnosc_srodk-1))/2) * krotnosc_dol;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",((krotnosc_srodk*(krotnosc_srodk-1))/2) * krotnosc_dol);
	 	 	 	 	 	 	}
	 	 	 	 	 	 else // Trzy różne wartości
	 	 	 	 	 	 	{
	 	 	 	 	 	 	 WYNIK += krotnosc_dol*krotnosc_srodk*krotnosc_gora;
//	 	 	 	 	 	 	 printf("WYNIK += %lld\n",krotnosc_dol*krotnosc_srodk*krotnosc_gora);
	 	 	 	 	 	 	}
	 	 	 	 	 	}
	 	 	 	 	 
	 	 	 	 	}
	 	 	 	 
	 	 	 	 
	 	 	 	 
	 	 	 	}
	 	 	 
	 	 	 if (-SUMA <= wartosc_dol)
	 	 	 	{
	 	 	 	 Start_ind_gora = ind_gora;
	 	 	 	}
	 	 	 if (-SUMA >= wartosc_gora)   stopstop=1;
	 	 	 if (ind_dol>ind_gora)  { stop=1; }
	 	 	 // Muszę odjąć to, co dodałem.
	 	 	 SUMA -= wartosc_gora;
	 	 	}
	 	 
	 	 if (ind_dol>mniejsze[0])   if ( indeksy [ind_dol - mniejsze[0]] - GRANICA >= 0)   stop=1;
	 	}
	 
	}
/* else
	{ // Idziemy od strony dodatniej
	 ind_gora= mniejsze[0] + licz_ind + wieksze[0] + 1; 
	 stop = 0;
	 while (!stop)
	 	{
	 	 ind_gora--;
	 	 // Dla tego indeksu przelatuję po kolei w dół, szukając, co da się złożyć
	 	 
	 	 if (ind_gora > mniejsze[0] + licz_ind)   
		 	{
		 	 wartosc_gora = wieksze[ind_gora - mniejsze[0] - licz_ind];
		 	 krotnosc_gora = krot_wieksze[ind_gora - mniejsze[0] - licz_ind];
		 	 SUMA = wartosc_gora; // Mała suma - dwóch pierwszych
			 if (krotnosc_gora > 1 )   ind_srod = ind_gora+1;
			 else   ind_srod = ind_gora;
			}
		 else  // Jeśli jest już w krotnosciach
		 	{
		 	 wartosc_gora = indeksy[ ind_gora-mniejsze[0] ] - GRANICA;
		 	 krotnosc_gora = krotnosci[ indeksy[ ind_gora-mniejsze[0] ] ];
		 	 SUMA = wartosc_gora;
		 	 if ( krotnosc_gora > 1 )   ind_srod = ind_gora+1;
		 	 else   ind_srod = ind_gora;
		 	}
	 	 
	 	 
	 	 
	 	 
	 	 stopstop=0;
	 	 
	 	 while (!stopstop) // Pętla dla drugiego indeksu
	 	 	{
	 	 	 ind_srod++;
	 	 	 // Dodaję do tego, co już mam
	 	 	 if (ind_srod <= mniejsze[0])   
		     	{
				 wartosc_srodk = mniejsze[ind_srod];
				 krotnosc_srodk = krot_mniejsze[ind_srod];
				 SUMA += wartosc_srodk;
				}
	 	 	 else if (ind_srod - mniejsze[0] <= licz_ind)
	 	 	 	{
	 	 	 	 wartosc_srodk = indeksy[ind_srod-mniejsze[0]] - GRANICA;
	 	 	 	 krotnosc_srodk = krotnosci[ indeksy[ind_srod-mniejsze[0]] ];
	 	 	 	 SUMA += wartosc_srodk;
	 	 	 	}
	 	 	 else
	 	 	 	{ //Szukam w większych
	 	 	 	 wartosc_srodk = wieksze[ind_srod - mniejsze[0] - licz_ind];
	 	 	 	 krotnosc_srodk = krot_wieksze[ind_srod - mniejsze[0] - licz_ind];
	 	 	 	 SUMA += wartosc_srodk;
	 	 	 	}
	 	 	 
//	 	 	 printf("(ind=%ld) wart=%ld (krot=%ld)   +   (ind=%ld) wart=%ld (krot=%ld)   => Szukam wart=%ld\n",ind_dol,wartosc_dol,krotnosc_dol,  ind_srod,wartosc_srodk,krotnosc_srodk, -SUMA );
//	 	 	 getch(); //////////////////////////////////////////////////////////////////////////////////////////////////
	 	 	 	 	 
	 	 
	 	 
	 	 
	 	 if (ind_gora <= mniejsze[0] + licz_ind)   if ( indeksy [ind_gora - mniejsze[0]] - GRANICA <= 0)   stop=1;
	 	}
	 
	}
*/

printf("%lld",WYNIK);


return 0;
}




