#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int INT() {
int in; scanf("%d", &in);
return in;
}
vector <int> pref;
int sum(int l, int r) {
return pref[r]-(l ? pref[l-1] : 0);
}
int main() {
int n=INT();
vector <int> a(n);
for(int &x : a) x=INT();
pref.resize(n);
pref[0]=a[0];
for(int i=1; i<n; ++i) pref[i]=pref[i-1]+a[i];
ll ans=0ll;
unordered_map <int, int> p3, pi; // p3 - trzy prefiksy, pi - prefiks i przedzial
p3[0]=1;
int off1=0, off3=0;
for(int x=n-1; x>=0; --x) {
// lll
ans+=p3[-3*a[x]-off3];
for(int i=0; i<x; ++i) ans+=3*p3[-2*a[x]-sum(i, x)-off3]+3*p3[-a[x]-2*sum(i, x)-off3];
for(int i=0; i<x; ++i) for(int j=i+1; j<x; ++j) ans+=6*p3[-a[x]-sum(i, x)-sum(j, x)-off3];
//for(int i=0; i<x; ++i) for(int j=i+1; j<x; ++j) if(sum(i, x)+sum(j, x)+a[x]==0) ++ans;
//printf("ans after lll: %lld\n", ans);
// lrl
for(int i=0; i<x; ++i) for(int j=i; j<x; ++j) ans+=pi[-a[x]-sum(i, j)-off1];
//printf("ans after lrl: %lld\n", ans);
// llr
//ans+=pi[-2*a[x]-off1];
for(int i=0; i<=x; ++i) for(int j=0; j<=x; ++j) ans+=pi[-sum(i, x)-sum(j, x)-off1];
//printf("ans after llr: %lld\n", ans);
off1+=a[x], off3+=3*a[x];
// rrr
++p3[3*a[x]-off3];
for(int i=x+1; i<n; ++i) p3[2*a[x]+sum(x, i)-off3]+=3, p3[a[x]+2*sum(x, i)-off3]+=3;
for(int i=x+1; i<n; ++i) for(int j=i+1; j<n; ++j) p3[a[x]+sum(x, i)+sum(x, j)-off3]+=6;
// rlr
for(int i=x+1; i<n; ++i) for(int j=i; j<n; ++j) ++pi[a[x]+sum(i, j)-off1];
// lrr
//++pi[2*a[x]-off1];
for(int i=x; i<n; ++i) for(int j=x; j<n; ++j) ++pi[sum(x, i)+sum(x, j)-off1];
/*printf("pi: ");
for(auto &p : pi) if(p.second) printf("%d %d ", p.first+off1, p.second);
printf("\n");
printf("p3: ");
for(auto &p : p3) if(p.second) printf("%d %d ", p.first+off3, p.second);
printf("\n\n");*/
}
unordered_map <int, int> amount; // ile przedzialow o danej sumie
for(int i=0; i<n; ++i) for(int j=i; j<n; ++j) ++amount[sum(i, j)];
ll zeros=0;
for(int i=0; i<n; ++i) for(int j=i; j<n; ++j) {
if(sum(i, j)) ans-=amount[-2*sum(i, j)];
else ++zeros;
}
if(zeros) ans-=zeros, ans-=zeros*(zeros-1ll);
printf("%lld\n", ans);
exit(0);
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #include <bits/stdc++.h> using namespace std; typedef long long ll; int INT() { int in; scanf("%d", &in); return in; } vector <int> pref; int sum(int l, int r) { return pref[r]-(l ? pref[l-1] : 0); } int main() { int n=INT(); vector <int> a(n); for(int &x : a) x=INT(); pref.resize(n); pref[0]=a[0]; for(int i=1; i<n; ++i) pref[i]=pref[i-1]+a[i]; ll ans=0ll; unordered_map <int, int> p3, pi; // p3 - trzy prefiksy, pi - prefiks i przedzial p3[0]=1; int off1=0, off3=0; for(int x=n-1; x>=0; --x) { // lll ans+=p3[-3*a[x]-off3]; for(int i=0; i<x; ++i) ans+=3*p3[-2*a[x]-sum(i, x)-off3]+3*p3[-a[x]-2*sum(i, x)-off3]; for(int i=0; i<x; ++i) for(int j=i+1; j<x; ++j) ans+=6*p3[-a[x]-sum(i, x)-sum(j, x)-off3]; //for(int i=0; i<x; ++i) for(int j=i+1; j<x; ++j) if(sum(i, x)+sum(j, x)+a[x]==0) ++ans; //printf("ans after lll: %lld\n", ans); // lrl for(int i=0; i<x; ++i) for(int j=i; j<x; ++j) ans+=pi[-a[x]-sum(i, j)-off1]; //printf("ans after lrl: %lld\n", ans); // llr //ans+=pi[-2*a[x]-off1]; for(int i=0; i<=x; ++i) for(int j=0; j<=x; ++j) ans+=pi[-sum(i, x)-sum(j, x)-off1]; //printf("ans after llr: %lld\n", ans); off1+=a[x], off3+=3*a[x]; // rrr ++p3[3*a[x]-off3]; for(int i=x+1; i<n; ++i) p3[2*a[x]+sum(x, i)-off3]+=3, p3[a[x]+2*sum(x, i)-off3]+=3; for(int i=x+1; i<n; ++i) for(int j=i+1; j<n; ++j) p3[a[x]+sum(x, i)+sum(x, j)-off3]+=6; // rlr for(int i=x+1; i<n; ++i) for(int j=i; j<n; ++j) ++pi[a[x]+sum(i, j)-off1]; // lrr //++pi[2*a[x]-off1]; for(int i=x; i<n; ++i) for(int j=x; j<n; ++j) ++pi[sum(x, i)+sum(x, j)-off1]; /*printf("pi: "); for(auto &p : pi) if(p.second) printf("%d %d ", p.first+off1, p.second); printf("\n"); printf("p3: "); for(auto &p : p3) if(p.second) printf("%d %d ", p.first+off3, p.second); printf("\n\n");*/ } unordered_map <int, int> amount; // ile przedzialow o danej sumie for(int i=0; i<n; ++i) for(int j=i; j<n; ++j) ++amount[sum(i, j)]; ll zeros=0; for(int i=0; i<n; ++i) for(int j=i; j<n; ++j) { if(sum(i, j)) ans-=amount[-2*sum(i, j)]; else ++zeros; } if(zeros) ans-=zeros, ans-=zeros*(zeros-1ll); printf("%lld\n", ans); exit(0); } |
English