#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
using namespace std;
//O(N)
long long square_sum(const vector<long long>& A){
long long ret = 0;
int n = A.size();
long long s0 = 0; //ΣAi
long long s1 = 0; //ΣΣAi
long long s2 = 0; //Σ(ΣAi)^2
for(int i=0; i<n; i++){
s0 += A[i];
ret += (i+1)*s0*s0 - 2*s0*s1 + s2;
s1 += s0;
s2 += s0*s0;
}
return ret;
}
//O(N^2)
long long square_sum_O_N2(const vector<long long>& A){
long long ret = 0;
int n = A.size();
for(int r=0; r<n; r++){
long long s = 0;
for(int l=r; l>=0; l--){
s += A[l];
ret += s*s;
}
}
return ret;
}
//O(N^2)
long long square_sum_O_N2_accumulate(const vector<long long>& A){
long long ret = 0;
int n = A.size();
vector<long long> acc(n+1, 0);
for(int i=0; i<n; i++) acc[i+1] = acc[i] + A[i];
for(int l=0; l<n; l++){
for(int r=l+1; r<=n; r++){
long long s = acc[r]-acc[l];
ret += s*s;
}
}
return ret;
}
//O(N^3)
long long square_sum_O_N3(const vector<long long>& A){
long long ret = 0;
int n = A.size();
for(int l=0; l<n; l++){
for(int r=l; r<n; r++){
long long s = 0;
for(int i=l; i<=r; i++){
s += A[i];
}
ret += s*s;
}
}
return ret;
}
int main(){
long long n = 3000;
vector<long long> v(n, 1);
random_device rnd;
mt19937 mt(rnd());
uniform_int_distribution<long long> dstr(-10, 10);
generate(v.begin(), v.end(), [&](){return dstr(mt);});
long long ans;
auto s = chrono::system_clock::now();
ans = square_sum(v);
auto t = chrono::system_clock::now();
cout << "O(N) : " << chrono::duration_cast<chrono::milliseconds>(t-s).count() << " ms" << endl;
cout << ans << endl;
s = chrono::system_clock::now();
ans = square_sum_O_N2(v);
t = chrono::system_clock::now();
cout << "O(N^2) : " << chrono::duration_cast<chrono::milliseconds>(t-s).count() << " ms" << endl;
cout << ans << endl;
s = chrono::system_clock::now();
ans = square_sum_O_N2_accumulate(v);
t = chrono::system_clock::now();
cout << "O(N^2) : " << chrono::duration_cast<chrono::milliseconds>(t-s).count() << " ms" << endl;
cout << ans << endl;
s = chrono::system_clock::now();
ans = square_sum_O_N3(v);
t = chrono::system_clock::now();
cout << "O(N^3) : " << chrono::duration_cast<chrono::milliseconds>(t-s).count() << " ms" << endl;
cout << ans << endl;
return 0;
}