Problem:
Problem
長さ $N$ の数列 $S$ があります。ここで数列 $S$ の各要素を整数 $i$ を用いて $S_i \ (0 \le i \lt N)$ と表します。
以下の条件を全て満たす整数の組 $(a, b, c)$ の個数を数えてください。
$0 \le a \le b \lt N$
$0 \le c \le b - a$
長さ $N$ の数列 $T$ の各要素 $T_i \ (0 \le i \lt N)$ を以下のように定めたとき、数列 $S$ が数列 $T$ と等しい。
		\begin{equation*}
		T_i =  \left \{
		\begin{array}{ll}
		S_{a + ((i - a + c) \bmod (b - a + 1))}&  {\rm if} \ \ \ a \le i \le b\\
		S_i&  {\rm otherwise} \\
		\end{array}
		\right.
		\end{equation*}
ただし、非負整数 $x$ と 正の整数 $y$ に対し $x \bmod y$ とは $x$ を $y$ で割ったあまりを表します。
Input
入力は以下の形式で与えられる。
$N$
$S_0$ $S_1$ $...$ $S_{N-1}$
Constraints
入力は以下の条件を満たす。
$1 \le N \le 2 \times 10^5$
$0 \le $ $S_i$ $\le 10^9$
入力はすべて整数である
Ouput
答えを一行に出力せよ。
Sample Input 1
3
1 2 2
Sample Output 1
7
条件を満たす組は $(0,0,0),(0,1,0),(0,2,0),(1,1,0),(1,2,0),(1,2,1),(2,2,0)$ の $7$ 個です。
Sample Input 2
10
1 2 1 2 3 1 2 1 2 3
Sample Output 2
58
Sample Input 3
17
7 0 7 3 3 1 1 3 0 4 1 6 3 9 3 0 2
Sample Output 3
155

Submitted solutions:

code_snippet: // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3081

#include<bits/stdc++.h>
using namespace std;

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
// longest common prefix of s and s[i:n]
template<typename T>
vector<int> zalgorithm(vector<T> vs){
  int n=vs.size();
  vector<int> as(n+1,0);
  as[0]=n;
  int i=1,j=0;
  while(i<n){
    while(i+j<n&&vs[j]==vs[i+j]) j++;
    as[i]=j;
    if(j==0){
      i++;
      continue;
    }
    int k=1;
    while(i+k<n&&k+as[k]<j) as[i+k]=as[k],k++;
    i+=k;
    j-=k;
  }
  return as;
}
vector<int> zalgorithm(string s){
  return zalgorithm(vector<char>(s.begin(),s.end()));
}
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;

#define call_from_test
#include "zalgorithm.cpp"
#undef call_from_test

#endif
//BEGIN CUT HERE
namespace Run{
  using T = tuple<int, int, int>;
  using P = pair<int, int>;
  vector<vector<P>> run;

  template<typename C>
  vector<T> sub(const vector<C> &xs,const vector<C> &ys){
    auto ps=xs;
    auto qs=ys;
    reverse(ps.begin(),ps.end());
    qs.insert(qs.end(),xs.begin(),xs.end());
    qs.insert(qs.end(),ys.begin(),ys.end());
    auto zp=zalgorithm(ps);
    auto zq=zalgorithm(qs);
    vector<T> res;
    for(int i=0;i<(int)xs.size();i++){
      int a=xs.size()-i;
      int b=i-zp[a];
      int c=max(0,(int)ys.size()-zq[ys.size()+i]);
      if((int)(xs.size()+ys.size())-b-c>=2*a)
        res.emplace_back(a,b,c);
    }
    return res;
  }

  template<typename C>
  void dfs(int l,int r,const vector<C> &cs){
    if(l+1>=r) return;
    int m=(l+r)>>1;
    vector<C> xs(cs.begin()+l,cs.begin()+m);
    vector<C> ys(cs.begin()+m,cs.begin()+r);
    {
      auto zs=sub(xs,ys);
      for(auto w:zs){
        int a,b,c;
        tie(a,b,c)=w;
        run[a].emplace_back(l+b,r-c);
      }
    }
    reverse(xs.begin(),xs.end());
    reverse(ys.begin(),ys.end());
    {
      auto zs=sub(ys,xs);
      for(auto w:zs){
        int a,b,c;
        tie(a,b,c)=w;
        run[a].emplace_back(l+c,r-b);
      }
    }
    dfs(l,m,cs);
    dfs(m,r,cs);
  }

  // return all t (not only minimal)
  template<typename C>
  vector<vector<P>> enumerate(const vector<C> &cs){
    int n=cs.size();
    run.clear();
    run.resize(n+1);
    dfs(0,n,cs);

    auto cmp=[&](P a,P b){return P(a.first,-a.second)<P(b.first,-b.second);};
    for(int i=1;i<=n;i++){
      auto &rs=run[i];
      sort(rs.begin(),rs.end(),cmp);
      int mx=-1;
      vector<P> tmp;
      for(auto p:rs){
        if(mx<p.second){
          tmp.emplace_back(p);
          mx=p.second;
        }
      }
      rs=tmp;
    }
    return run;
  }

  vector<vector<P>> enumerate(string ss){
    return enumerate(vector<char>(ss.begin(),ss.end()));
  }
};
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#undef call_from_test

//INSERT ABOVE HERE
signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n;
  cin>>n;
  vector<int> as(n);
  for(int i=0;i<n;i++) cin>>as[i];

  auto run=Run::enumerate(as);
  using ll = long long;
  vector<ll> dp(n+1,0),sm(n+1,0);
  for(ll i=1;i<=n;i++){
    dp[i]=dp[i-1]+(i-1)*1;
    sm[i]=sm[i-1]+(i-1)*i;
  }

  auto calc=[&](ll t,ll len)->ll{
    return (len+1)*dp[len/t]-t*sm[len/t];
  };

  ll ans=(ll)n*(n+1)/2;
  set<Run::P> used;
  for(int t=1;t<=n;t++){
    for(auto p:run[t]){
      if(used.count(p)) continue;
      used.emplace(p);
      ans+=calc(t,p.second-p.first);
    }
  }
  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 49956
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}


struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;


// longest common prefix of s and s[i:n]
template<typename T>
vector<int> zalgorithm(vector<T> vs){
  int n=vs.size();
  vector<int> as(n+1,0);
  as[0]=n;
  int i=1,j=0;
  while(i<n){
    while(i+j<n&&vs[j]==vs[i+j]) j++;
    as[i]=j;
    if(j==0){
      i++;
      continue;
    }
    int k=1;
    while(i+k<n&&k+as[k]<j) as[i+k]=as[k],k++;
    i+=k;
    j-=k;
  }
  return as;
}
vector<int> zalgorithm(string s){
  return zalgorithm(vector<char>(s.begin(),s.end()));
}


namespace Run{
  using T = tuple<int, int, int>;
  using P = pair<int, int>;
  vector<vector<P>> run;

  template<typename C>
  vector<T> sub(const vector<C> &xs,const vector<C> &ys){
    auto ps=xs;
    auto qs=ys;
    reverse(ps.begin(),ps.end());
    qs.insert(qs.end(),xs.begin(),xs.end());
    qs.insert(qs.end(),ys.begin(),ys.end());
    auto zp=zalgorithm(ps);
    auto zq=zalgorithm(qs);
    vector<T> res;
    for(int i=0;i<(int)xs.size();i++){
      int a=xs.size()-i;
      int b=i-zp[a];
      int c=max(0,(int)ys.size()-zq[ys.size()+i]);
      if((int)(xs.size()+ys.size())-b-c>=2*a)
        res.emplace_back(a,b,c);
    }
    return res;
  }

  template<typename C>
  void dfs(int l,int r,const vector<C> &cs){
    if(l+1>=r) return;
    int m=(l+r)>>1;
    vector<C> xs(cs.begin()+l,cs.begin()+m);
    vector<C> ys(cs.begin()+m,cs.begin()+r);
    {
      auto zs=sub(xs,ys);
      for(auto w:zs){
        int a,b,c;
        tie(a,b,c)=w;
        run[a].emplace_back(l+b,r-c);
      }
    }
    reverse(xs.begin(),xs.end());
    reverse(ys.begin(),ys.end());
    {
      auto zs=sub(ys,xs);
      for(auto w:zs){
        int a,b,c;
        tie(a,b,c)=w;
        run[a].emplace_back(l+c,r-b);
      }
    }
    dfs(l,m,cs);
    dfs(m,r,cs);
  }

  // return all t (not only minimal)
  template<typename C>
  vector<vector<P>> enumerate(const vector<C> &cs){
    int n=cs.size();
    run.clear();
    run.resize(n+1);
    dfs(0,n,cs);

    auto cmp=[&](P a,P b){return P(a.first,-a.second)<P(b.first,-b.second);};
    for(int i=1;i<=n;i++){
      auto &rs=run[i];
      sort(rs.begin(),rs.end(),cmp);
      int mx=-1;
      vector<P> tmp;
      for(auto p:rs){
        if(mx<p.second){
          tmp.emplace_back(p);
          mx=p.second;
        }
      }
      rs=tmp;
    }
    return run;
  }

  vector<vector<P>> enumerate(string ss){
    return enumerate(vector<char>(ss.begin(),ss.end()));
  }
};

//INSERT ABOVE HERE
signed main(){
  int n;
  cin>>n;
  vector<int> as(n);
  for(int i=0;i<n;i++) cin>>as[i];

  auto run=Run::enumerate(as);
  using ll = long long;
  vector<ll> dp(n+1,0),sm(n+1,0);
  for(ll i=1;i<=n;i++){
    dp[i]=dp[i-1]+(i-1)*1;
    sm[i]=sm[i-1]+(i-1)*i;
  }

  auto calc=
    [&](ll t,ll len)->ll{
      return (len+1)*dp[len/t]-t*sm[len/t];
    };

  ll ans=(ll)n*(n+1)/2;
  set<Run::P> used;
  for(int t=1;t<=n;t++){
    for(auto p:run[t]){
      if(used.count(p)) continue;
      used.emplace(p);
      ans+=calc(t,p.second-p.first);
    }
  }
  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 49668
final_rank: 5

code_snippet: #include<bits/stdc++.h>
#define popcount __builtin_popcount

using namespace std;

#define int long long
#define endl "\n"

// typedef long long int ll;
typedef pair<int, int> P;

vector< int > z_algorithm(const vector<int> &s) {
  vector< int > prefix(s.size());
  for(int i = 1, j = 0; i < s.size(); i++) {
    if(i + prefix[i - j] < j + prefix[j]) {
      prefix[i] = prefix[i - j];
    } else {
      int k = max(0ll, j + prefix[j] - i);
      while(i + k < s.size() && s[k] == s[i + k]) ++k;
      prefix[i] = k;
      j = i;
    }
  }
  prefix[0] = (int) s.size();
  return prefix;
}
vector<int> s;
vector<pair<int, P>> ans;
void solve(int l, int r){
	if(r-l<1) return;
	int m=(l+r)/2;
	int n=r-l+1;
	vector<int> s1, s2;
	// for(int i=m; i>=l; i--) s1+=s[i];
	for(int i=m; i>=l; i--) s1.push_back(s[i]);
	// s1+='#';
	s1.push_back(-1);
	// for(int i=r; i>=l; i--) s1+=s[i];
	for(int i=r; i>=l; i--) s1.push_back(s[i]);
	// for(int i=m+1; i<=r; i++) s2+=s[i];
	for(int i=m+1; i<=r; i++) s2.push_back(s[i]);
	// s2+='#';
	s2.push_back(-1);
	// for(int i=l; i<=r; i++) s2+=s[i];
	for(int i=l; i<=r; i++) s2.push_back(s[i]);
	vector<int> z1=z_algorithm(s1), z2=z_algorithm(s2);
	vector<int> used(n);
	for(int i=m; i>=l; i--){
		if(used[i-l]) continue;
		int t=m-i+1;
		int x=z1[t], y=z2[r-m+i-l+1];
		if(x+y>=t && y>0 && !(m-t-x>=0 && s[m-t-x]==s[m-x]) && !(m+y+1<s.size() && s[m+y+1]==s[m+y+1-t])) ans.push_back({t, {m-t-x+1, m+y+1}});
		for(int j=m-t+1; m-j+1<=x+t; j-=t) used[j-l]=1;
		for(int j=m+t; j<=m+y; j+=t) used[j-l]=1;
	}
	for(int i=m+1; i<=r; i++){
		if(used[i-l]) continue;
		int t=i-m;
		int x=z1[m-l+2+r-i], y=z2[t];
		if(x+y>=t && x>0 && !(m-x>=0 && s[m-x]==s[m-x+t]) && !(m+t+y+1<s.size() && s[m+t+y+1]==s[m+y+1])) ans.push_back({t, {m+1-x, m+t+y+1}});
		for(int j=i; j<=m+t+y; j+=t) used[j-l]=1;
	}
	solve(l, m);
	solve(m+1, r);
}

int solve4(vector<int> &A) {
	int res = (int)A.size()*(A.size()+1)/2;
	
	s = A;
	ans.clear();
	
	
	solve(0, (int)s.size()-1);
	
	for(int i = 0; i < ans.size(); i++){
		int x = ans[i].second.second - ans[i].second.first;
		int num = x / ans[i].first;
		
		num--;

		
		res += ((num * (num + 1)/ 2 + num * (num + 1) * (2 * num + 1) / 6) / 2 ) * (x%ans[i].first + 1);
		num--;
		res += ((num * (num + 1)/ 2 + num * (num + 1) * (2 * num + 1) / 6) / 2 ) * (ans[i].first - (x%ans[i].first + 1));
	}
	
	return res;	
}

signed main(){
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	
	int N;
	vector<int> A, A2, A3, A4;
	
	cin>>N;
	
	A.resize(N);
	
	for(int i = 0; i < N; i++){
		cin>>A[i];
	}
	
	cout<<solve4(A)<<endl;
	
	
	return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 34160
final_rank: 3

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <array>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#include <cassert>
#include <iomanip>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;


typedef array<int, 3> ary;
// Reference:
// D. Gusfield,
// Algorithms on Strings, Trees, and Sequences: Computer Science and
// Computational Biology
template <class T> vector<int> z_algorithm(const vector<T>& s) {
  int n = int(s.size());
  if (n == 0) return {};
  vector<int> z(n);
  z[0] = 0;
  for (int i = 1, j = 0; i < n; i++) {
    int& k = z[i];
    k = (j + z[j] <= i) ? 0 : min(j + z[j] - i, z[i - j]);
    while (i + k < n && s[k] == s[i + k]) k++;
    if (j + z[j] < i + z[i]) j = i;
  }
  z[0] = n;
  return z;
}

vector<int> z_algorithm(const string& s) {
  int n = int(s.size());
  vector<int> s2(n);
  for (int i = 0; i < n; i++) {
    s2[i] = s[i];
  }
  return z_algorithm(s2);
}

template<typename T, T INF>
void Main_Lorentz(const vector<T>& s, const vector<T>& rev, vector<ary>& ret, int l=0, int r=-1){
  int n = (int)s.size();
  if(r==-1) r = (int)s.size();
  if(r-l<2) return;
  int mid = (l + r)/2;

  vector<T> L(mid-l), R(r-mid), R2(r-mid+1+r-l), L2(mid-l+1+r-l);
  for(int i=0;i<mid-l;i++) L[i] = L2[i] = rev[n-mid+i];
  for(int i=0;i<r-mid;i++) R[i] = R2[i] = s[mid+i];
  L2[mid-l] = R2[r-mid] = INF;//insert #
  for(int i=0;i<r-l;i++){
    R2[r-mid+1+i] = s[l+i];
    L2[mid-l+1+i] = rev[n-r+i];
  }

  vector<int> z1 = z_algorithm<T>(L);
  vector<int> z2 = z_algorithm<T>(R2);
  int len = r - l;
  for(int i=0;i<mid-l;i++){
    int x = i;
    int y = z1[i];
    if(i==0) x = mid - l, y = 0;
    int z = z2[len+1-x];
    int lidx = mid - x - y, ridx = mid + z;
    if(x>0&&z>0&&(y+z)>=x) ret.push_back({x, lidx, ridx});//周期, [l, r)
  }
  z1 = z_algorithm<T>(R);
  z2 = z_algorithm<T>(L2);

  for(int i=0;i<r-mid;i++){
    int x = i;
    int y = z1[i];
    if(i==0) x = r-mid, y = 0;
    int z = z2[len+1-x];
    int ridx = n - (n - mid - x - y), lidx = n - (n - mid + z);
    if(x>0&&z>0&&(y+z)>=x) ret.push_back({x, lidx, ridx});//周期, [l, r)
  }
  Main_Lorentz<T, INF>(s, rev, ret, l, mid);
  Main_Lorentz<T, INF>(s, rev, ret, mid, r);
}

template<typename T, T INF>
vector<ary> Main_Lorentz(const vector<T>& s){
  int n = (int)s.size();
  //(t, l, r)は周期tを持つ
  //同じ(l, r)での周期を最小にする
  //同じ(l, 周期)でのrを最大化する
  //同じ(r, 周期)でのlを最小化する
  vector<ary> tmp, ret;
  vector<T> t = s;
  reverse(all(t));
  Main_Lorentz<T, INF>(s, t, tmp);
  sort(all(tmp), [&](const ary& x, const ary& y){
    if(x[0]!=y[0]) return x[0] < y[0];
    if(x[1]!=y[1]) return x[1] < y[1];
                   return x[2] > y[2];
  });
  int l = 1000000000, r = -1000000000;
  set<array<int, 2>> st;
  for(int i=0;i<(int)tmp.size();i++){
    ary v = tmp[i];
    if(i&&v[0]!=tmp[i-1][0]) l = 1000000000, r = -1000000000;
    if(v[1]>=l&&v[2]<=r) continue;
    if(n<v[2]) continue;
    l = min(l, v[1]);
    r = max(r, v[2]);
    if(st.find({v[1], v[2]})!=st.end()) continue;
    ret.push_back(v);
    st.insert({v[1], v[2]});
  }
  return ret;
}

void Main_Lorentz(const string& s, const string& rev, vector<ary>& ret, int l=0, int r=-1){
  int n = (int)s.size();
  if(r==-1) r = (int)s.size();
  if(r-l<2) return;
  int mid = (l + r)/2;

  string L = rev.substr(n-mid, mid - l);
  string R = s.substr(mid, r - mid);
  vector<int> z1 = z_algorithm(L);
  vector<int> z2 = z_algorithm(R + "#" + s.substr(l, r - l));
  int len = r - l;
  for(int i=0;i<mid-l;i++){
    int x = i;
    int y = z1[i];
    if(i==0) x = mid - l, y = 0;
    int z = z2[len+1-x];
    int lidx = mid - x - y, ridx = mid + z;
    if(x>0&&z>0&&(y+z)>=x) ret.push_back({x, lidx, ridx});//周期, [l, r)
  }
  z1 = z_algorithm(R);
  z2 = z_algorithm(L + "#" + rev.substr(n-r, r - l));
  for(int i=0;i<r-mid;i++){
    int x = i;
    int y = z1[i];
    if(i==0) x = r-mid, y = 0;
    int z = z2[len+1-x];
    int ridx = n - (n - mid - x - y), lidx = n - (n - mid + z);
    if(x>0&&z>0&&(y+z)>=x) ret.push_back({x, lidx, ridx});//周期, [l, r)
  }
  Main_Lorentz(s, rev, ret, l, mid);
  Main_Lorentz(s, rev, ret, mid, r);
}

vector<ary> Main_Lorentz(const string& s){
  int n = (int)s.size();
  //(t, l, r)は周期tを持つ
  //同じ(l, r)での周期を最小にする
  //同じ(l, 周期)でのrを最大化する
  //同じ(r, 周期)でのlを最小化する
  vector<ary> tmp, ret;
  string t = s;
  reverse(all(t));
  Main_Lorentz(s, t, tmp);
  sort(all(tmp), [&](const ary& x, const ary& y){
    if(x[0]!=y[0]) return x[0] < y[0];
    if(x[1]!=y[1]) return x[1] < y[1];
                   return x[2] > y[2];
  });
  int l = 1000000000, r = -1000000000;
  set<array<int, 2>> st;
  for(int i=0;i<(int)tmp.size();i++){
    ary v = tmp[i];
    if(i&&v[0]!=tmp[i-1][0]) l = 1000000000, r = -1000000000;
    if(v[1]>=l&&v[2]<=r) continue;
    if(n<v[2]) continue;
    l = min(l, v[1]);
    r = max(r, v[2]);
    if(st.find({v[1], v[2]})!=st.end()) continue;
    ret.push_back(v);
    st.insert({v[1], v[2]});
  }
  return ret;
}

int main(){
  ll n;scanf("%lld", &n);
  vector<int> v(n);
  for(int i=0;i<n;i++) scanf("%d", &v[i]);
  auto dat = Main_Lorentz<int, 2000000000>(v);
  ll ans = (n * (n+1))/2;//幅0

  for(auto e:dat){
    ll l = e[2] - e[1];
    ll p = e[0];
    ll m = l/p;

    ans += m*(m+1)/2*(p+l+1) - m*(m+1)*(2*m+1)/6*p - m*(l+1);
  }

  printf("%lld\n", ans);
}
accuracy: 1
time_ms: 410
memory_kb: 65088
final_rank: 12

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <array>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#include <cassert>
#include <iomanip>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;


typedef array<int, 3> ary;
// Reference:
// D. Gusfield,
// Algorithms on Strings, Trees, and Sequences: Computer Science and
// Computational Biology
template <class T> vector<int> z_algorithm(const vector<T>& s) {
  int n = int(s.size());
  if (n == 0) return {};
  vector<int> z(n);
  z[0] = 0;
  for (int i = 1, j = 0; i < n; i++) {
    int& k = z[i];
    k = (j + z[j] <= i) ? 0 : min(j + z[j] - i, z[i - j]);
    while (i + k < n && s[k] == s[i + k]) k++;
    if (j + z[j] < i + z[i]) j = i;
  }
  z[0] = n;
  return z;
}

vector<int> z_algorithm(const string& s) {
  int n = int(s.size());
  vector<int> s2(n);
  for (int i = 0; i < n; i++) {
    s2[i] = s[i];
  }
  return z_algorithm(s2);
}

template<typename T, T INF>
void Main_Lorentz(const vector<T>& s, const vector<T>& rev, vector<ary>& ret, int l=0, int r=-1){
  int n = (int)s.size();
  if(r==-1) r = (int)s.size();
  if(r-l<2) return;
  int mid = (l + r)/2;

  vector<T> L(mid-l), R(r-mid), R2(r-mid+1+r-l), L2(mid-l+1+r-l);
  for(int i=0;i<mid-l;i++) L[i] = L2[i] = rev[n-mid+i];
  for(int i=0;i<r-mid;i++) R[i] = R2[i] = s[mid+i];
  L2[mid-l] = R2[r-mid] = INF;//insert #
  for(int i=0;i<r-l;i++){
    R2[r-mid+1+i] = s[l+i];
    L2[mid-l+1+i] = rev[n-r+i];
  }

  vector<int> z1 = z_algorithm<T>(L);
  vector<int> z2 = z_algorithm<T>(R2);
  int len = r - l;
  for(int i=0;i<mid-l;i++){
    int x = i;
    int y = z1[i];
    if(i==0) x = mid - l, y = 0;
    int z = z2[len+1-x];
    int lidx = mid - x - y, ridx = mid + z;
    if(x>0&&z>0&&(y+z)>=x) ret.push_back({x, lidx, ridx});//周期, [l, r)
  }
  z1 = z_algorithm<T>(R);
  z2 = z_algorithm<T>(L2);

  for(int i=0;i<r-mid;i++){
    int x = i;
    int y = z1[i];
    if(i==0) x = r-mid, y = 0;
    int z = z2[len+1-x];
    int ridx = n - (n - mid - x - y), lidx = n - (n - mid + z);
    if(x>0&&z>0&&(y+z)>=x) ret.push_back({x, lidx, ridx});//周期, [l, r)
  }
  Main_Lorentz<T, INF>(s, rev, ret, l, mid);
  Main_Lorentz<T, INF>(s, rev, ret, mid, r);
}

template<typename T, T INF>
vector<ary> Main_Lorentz(const vector<T>& s){
  int n = (int)s.size();
  //(t, l, r)は周期tを持つ
  //同じ(l, r)での周期を最小にする
  //同じ(l, 周期)でのrを最大化する
  //同じ(r, 周期)でのlを最小化する
  vector<ary> tmp, ret;
  vector<T> t = s;
  reverse(all(t));
  Main_Lorentz<T, INF>(s, t, tmp);
  sort(all(tmp), [&](const ary& x, const ary& y){
    if(x[0]!=y[0]) return x[0] < y[0];
    if(x[1]!=y[1]) return x[1] < y[1];
                   return x[2] > y[2];
  });
  int l = 1000000000, r = -1000000000;
  set<array<int, 2>> st;
  for(int i=0;i<(int)tmp.size();i++){
    ary v = tmp[i];
    if(i&&v[0]!=tmp[i-1][0]) l = 1000000000, r = -1000000000;
    if(v[1]>=l&&v[2]<=r) continue;
    if(n<v[2]) continue;
    l = min(l, v[1]);
    r = max(r, v[2]);
    if(st.find({v[1], v[2]})!=st.end()) continue;
    ret.push_back(v);
    st.insert({v[1], v[2]});
  }
  return ret;
}

void Main_Lorentz(const string& s, const string& rev, vector<ary>& ret, int l=0, int r=-1){
  int n = (int)s.size();
  if(r==-1) r = (int)s.size();
  if(r-l<2) return;
  int mid = (l + r)/2;

  string L = rev.substr(n-mid, mid - l);
  string R = s.substr(mid, r - mid);
  vector<int> z1 = z_algorithm(L);
  vector<int> z2 = z_algorithm(R + "#" + s.substr(l, r - l));
  int len = r - l;
  for(int i=0;i<mid-l;i++){
    int x = i;
    int y = z1[i];
    if(i==0) x = mid - l, y = 0;
    int z = z2[len+1-x];
    int lidx = mid - x - y, ridx = mid + z;
    if(x>0&&z>0&&(y+z)>=x) ret.push_back({x, lidx, ridx});//周期, [l, r)
  }
  z1 = z_algorithm(R);
  z2 = z_algorithm(L + "#" + rev.substr(n-r, r - l));
  for(int i=0;i<r-mid;i++){
    int x = i;
    int y = z1[i];
    if(i==0) x = r-mid, y = 0;
    int z = z2[len+1-x];
    int ridx = n - (n - mid - x - y), lidx = n - (n - mid + z);
    if(x>0&&z>0&&(y+z)>=x) ret.push_back({x, lidx, ridx});//周期, [l, r)
  }
  Main_Lorentz(s, rev, ret, l, mid);
  Main_Lorentz(s, rev, ret, mid, r);
}

vector<ary> Main_Lorentz(const string& s){
  int n = (int)s.size();
  //(t, l, r)は周期tを持つ
  //同じ(l, r)での周期を最小にする
  //同じ(l, 周期)でのrを最大化する
  //同じ(r, 周期)でのlを最小化する
  vector<ary> tmp, ret;
  string t = s;
  reverse(all(t));
  Main_Lorentz(s, t, tmp);
  sort(all(tmp), [&](const ary& x, const ary& y){
    if(x[0]!=y[0]) return x[0] < y[0];
    if(x[1]!=y[1]) return x[1] < y[1];
                   return x[2] > y[2];
  });
  int l = 1000000000, r = -1000000000;
  set<array<int, 2>> st;
  for(int i=0;i<(int)tmp.size();i++){
    ary v = tmp[i];
    if(i&&v[0]!=tmp[i-1][0]) l = 1000000000, r = -1000000000;
    if(v[1]>=l&&v[2]<=r) continue;
    if(n<v[2]) continue;
    l = min(l, v[1]);
    r = max(r, v[2]);
    if(st.find({v[1], v[2]})!=st.end()) continue;
    ret.push_back(v);
    st.insert({v[1], v[2]});
  }
  return ret;
}

int main(){
  ll n;scanf("%lld", &n);
  vector<int> v(n);
  for(int i=0;i<n;i++) scanf("%d", &v[i]);
  auto dat = Main_Lorentz<int, 2000000000>(v);
  ll ans = (n * (n+1))/2;//幅0

  for(auto e:dat){
    //printf("%d %d %d\n", e[0], e[1], e[2]);
    ll w = (e[2] - e[1])/e[0];
    ll pl = (e[2] - e[1]) % e[0];//シフト可能
    ll mi = e[0] - pl;
    vector<ll> S(w+1, 0);
    //1の時は幅2以上の区間
    //2の時は幅3以上の区間...
    for(ll d=w;d>=1;d--){
      S[d] = w - d + 1;
      if(d!=w) S[d] += S[d+1];
    }
    for(ll d=1;d<w;d++) ans += (pl+1) * S[d+1];
    for(ll d=1;d<w;d++) ans += (mi - 1) * (S[d+1] - S[w]);
  }

  printf("%lld\n", ans);
}
accuracy: 0.375
time_ms: 380
memory_kb: 65208
final_rank: 15

code_snippet: #include <algorithm>
#include <array>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <numeric>
#include <string>
#include <utility>
#include <vector>
using namespace std;

typedef unsigned size_type;

#define USE_RMQ

template <class DatTp, class Comp = std::less<DatTp>> struct static_rmq {
    typedef unsigned long long ull;
    typedef unsigned size_type;

    std::vector<DatTp> data;
    Comp cmp;
    std::vector<std::vector<size_type>> sp_rmq;
    std::vector<ull> bl_tort;

    explicit static_rmq(const Comp &comp = Comp()) : cmp(comp) {}

    void init() {
        data.clear();
        sp_rmq.clear();
        bl_tort.clear();
    }

    template <class Iter> static_rmq(Iter beg, Iter en, const Comp &comp = Comp()) : cmp(comp) { init(beg, en); }

    template <class Iter> void init(Iter beg, Iter en) {
        sp_rmq.clear();
        bl_tort.clear();
        data.assign(beg, en);
        size_type sz = size();
        if(!sz) { return; }

        size_type sp_len = sz / 64;
        sp_rmq.reserve(64 - __builtin_clzll(sp_len | 1));

        std::vector<size_type> vec(sp_len);
        for(size_type i = 0; i < sp_len; ++i) {
            size_type t = i * 64;
            for(size_type j = t + 1; j < (i + 1) * 64; ++j) { t = minidx(t, j); }
            vec[i] = t;
        }
        sp_rmq.push_back(vec);

        for(size_type i = 1; (1u << i) <= sp_len; ++i) {
            vec.clear();
            size_type r = (1u << (i - 1));
            std::vector<size_type> &prv = sp_rmq.back();
            for(size_type j = 0; j + r * 2 <= sp_len; ++j) { vec.push_back(minidx(prv[j], prv[j + r])); }
            sp_rmq.push_back(vec);
        }

        bl_tort.assign(sz, 0ull);
        std::vector<size_type> st;
        st.reserve(64);
        for(size_type low = 0; low < sz; low += 64) {
            size_type high = std::min<size_type>(low + 64, sz);
            ull val = 0;
            st.clear();
            for(size_type j = high; j-- != low;) {
                while(!st.empty()) {
                    size_type tp = st.back();
                    if(cmp(data[tp], data[j])) { break; }
                    val ^= 1ull << (tp % 64);
                    st.pop_back();
                }
                st.push_back(j);
                val |= 1ull << (j % 64);
                bl_tort[j] = val;
            }
        }
    }

    size_type size() const { return data.size(); }

    size_type minidx(size_type i, size_type j) const {
        if(i > j) { std::swap(i, j); }
        // if(j >= size()){ return i; }
        return !cmp(data[j], data[i]) ? i : j;
    }

    const DatTp &operator[](size_type i) const { return data[i]; }

    // [lt, rt]
    size_type operator()(size_type lt, size_type rt) const {
        if(lt > rt) { return lt; }
        size_type bl_lt = lt / 64, bl_rt = rt / 64;
        size_type ret;
        ull rtmask = ((2ull << (rt % 64)) - 1);
        if(bl_lt == bl_rt) {
            ull bit = bl_tort[lt] & rtmask;
            size_type k = 63 - __builtin_clzll(bit);
            ret = bl_lt * 64 + k;
        } else {
            ret = bl_lt * 64 + 63 - __builtin_clzll(bl_tort[lt]);
            if(bl_lt + 1 != bl_rt) {
                size_type numblk = bl_rt - bl_lt - 1;
                size_type k = 63 - __builtin_clzll(numblk);
                size_type cand1 = sp_rmq[k][bl_lt + 1];
                ret = minidx(ret, cand1);
                if((1u << k) != numblk) {
                    size_type cand2 = sp_rmq[k][bl_rt - (1u << k)];
                    ret = minidx(ret, cand2);
                }
            }
            size_type cand3 = bl_rt * 64 + 63 - __builtin_clzll(bl_tort[bl_rt * 64] & rtmask);
            ret = minidx(ret, cand3);
        }
        return ret;
    }
};

struct suffix_array {
    typedef unsigned size_type;

    size_type size() const { return sa.size(); }

    size_type rank(size_type a) const { return rnk[a]; }

    size_type operator[](size_type x) const { return sa[x]; }

#ifdef USE_RMQ
    size_type lcp_order_adj(size_type a) const { return rmq[a]; }

    // lcp(S[a..], S[b..])
    size_type lcp(size_type a, size_type b) const {
        if(a >= size() || b >= size()) { return 0; }
        return lcp_ord(rnk[a], rnk[b]);
    }

    // [a,b] or [b,a]
    size_type lcp_ord(size_type a, size_type b) const {
        if(a == b) { return size() - sa[a]; }
        if(a > b) { std::swap(a, b); }
        size_type k = rmq(a + 1, b);
        return rmq[k];
    }

    int compsub(size_type pos1, size_type len1, size_type pos2, size_type len2) const {
        len1 = std::min(len1, size() - pos1);
        len2 = std::min(len2, size() - pos2);
        size_type com = lcp(pos1, pos2);
        com = std::min(com, std::min(len1, len2));
        if(com == len1) {
            if(com == len2) { return 0; }
            return -1;
        }
        if(com == len2) { return 1; }
        return rank(pos1) < rank(pos2) ? -2 : 2;
    }
#endif

    std::vector<size_type> sa;
    std::vector<size_type> rnk;
    std::vector<size_type> acc;
#ifdef USE_RMQ
    static_rmq<size_type> rmq;
#endif

    suffix_array() {}

    template <class Cont> explicit suffix_array(Cont &c) : suffix_array(c.begin(), c.end()) {}

    template <class RAI> suffix_array(RAI first, RAI last) { init(first, last); }

    void init() {
        sa.clear();
        rnk.clear();
        acc.clear();
#ifdef USE_RMQ
        rmq.init();
#endif
    }

    template <class Cont> void init(Cont &c) { init(c.begin(), c.end()); }

    template <class RAI> void init(RAI first, RAI last) {
        typedef typename std::iterator_traits<RAI>::value_type value_type;

        init();
        if(first == last) { return; }

        size_type len = std::distance(first, last);
        std::pair<RAI, RAI> minmax = std::minmax_element(first, last);
        if(*minmax.first < 0 || *minmax.second + size_type() > std::max<size_type>(len * 3, 250)) {
            std::vector<value_type> vec(first, last);
            std::sort(vec.begin(), vec.end());
            vec.erase(unique(vec.begin(), vec.end()), vec.end());
            std::vector<size_type> idx;
            idx.reserve(len);
            for(RAI it = first; it != last; ++it) { idx.push_back(std::lower_bound(vec.begin(), vec.end(), *it) - vec.begin()); }
            std::vector<value_type>().swap(vec);
            construct_sa_lcp(idx.begin(), idx.end());
        } else {
            construct_sa_lcp(first, last);
        }
    }

    template <class RAI> void construct_sa_lcp(RAI first, RAI last) {
        size_type kind = *std::max_element(first, last) + 1;
        size_type len = std::distance(first, last);
        acc.reserve(std::max(kind, len) + 1);
        sa = calcsa(first, last, kind);
        std::vector<size_type>().swap(acc);

        rnk.resize(len);
        for(size_type i = 0; i < len; ++i) { rnk[sa[i]] = i; }

        std::vector<size_type> lcpar(len);
        size_type h = 0;
        for(size_type i = 0; i < len; ++i) {
            if(rnk[i] == 0) {
                h = 0;
            } else {
                size_type j = sa[rnk[i] - 1];
                if(h > 0) { --h; }
                for(; j + h < len && i + h < len; ++h) {
                    if(first[j + h] != first[i + h]) { break; }
                }
            }
            lcpar[rnk[i]] = h;
        }
#ifdef USE_RMQ
        rmq.init(lcpar.begin(), lcpar.end());
#endif
    }

    void calcacc(const std::vector<size_type> &cnt) {
        acc.resize(cnt.size() + 1);
        acc[0] = 0;
        std::partial_sum(cnt.begin(), cnt.end(), acc.begin() + 1);
    }

    template <class RAI> std::vector<size_type> calcsa(RAI first, RAI last, size_type kind) {
        size_type len = std::distance(first, last);

        std::vector<size_type> cnt(kind);
        for(RAI it = first; it != last; ++it) { ++cnt[*it]; }

        std::vector<int> stype(len);
        for(size_type i = len - 1; i--;) {
            if(first[i] == first[i + 1]) {
                stype[i] = stype[i + 1];
            } else {
                stype[i] = (first[i] < first[i + 1]);
            }
        }
        std::vector<size_type> lms;
        size_type numlms = 0;
        std::vector<size_type> ridx(len, size_type(-1));

        std::vector<size_type> bucket(len, size_type(-1));
        calcacc(cnt);
        for(size_type i = 1; i < len; ++i) {
            if(stype[i] && !stype[i - 1]) {
                stype[i] = 2;
                bucket[--acc[first[i] + 1]] = i;
                ridx[i] = numlms++;
                lms.push_back(i);
            }
        }

        induced_sort(first, last, kind, stype, cnt, bucket);

        size_type lmskind = size_type(-1);
        std::vector<size_type> lmsstr(numlms);
        size_type prv = size_type(-1);
        for(size_type i = 0; i < len; ++i) {
            size_type r = ridx[bucket[i]];
            if(r != size_type(-1)) {
                if(prv == size_type(-1) || prv + 1 == numlms || r + 1 == numlms || lms[prv + 1] - lms[prv] != lms[r + 1] - lms[r] ||
                   !std::equal(first + lms[prv], first + (lms[prv + 1] + 1), first + lms[r])) {
                    ++lmskind;
                }
                lmsstr[r] = lmskind;
                prv = r;
            }
        }
        ++lmskind;

        std::vector<size_type> lmssa;
        if(lmskind != numlms) {
            lmssa = calcsa(lmsstr.begin(), lmsstr.end(), lmskind);
        } else {
            lmssa.resize(numlms);
            for(size_type i = 0; i < numlms; ++i) { lmssa[lmsstr[i]] = i; }
        }

        calcacc(cnt);
        bucket.assign(len, size_type(-1));
        for(size_type i = numlms; i--;) {
            size_type pos = lms[lmssa[i]];
            bucket[--acc[first[pos] + 1]] = pos;
        }
        induced_sort(first, last, kind, stype, cnt, bucket);

        return bucket;
    }

    template <class RAI>
    void induced_sort(RAI first, RAI last, size_type kind, const std::vector<int> &stype, std::vector<size_type> &cnt, std::vector<size_type> &bucket) {
        size_type len = std::distance(first, last);
        calcacc(cnt);
        bucket[acc[+first[len - 1]]++] = len - 1;
        for(size_type i = 0; i < len; ++i) {
            size_type bc = bucket[i];
            if(bc != size_type(-1) && bc != 0 && !stype[bc - 1]) { bucket[acc[+first[bc - 1]]++] = bc - 1; }
        }
        calcacc(cnt);
        for(size_type i = len; i--;) {
            size_type bc = bucket[i];
            if(bc != size_type(-1) && bc != 0 && stype[bc - 1]) { bucket[--acc[first[bc - 1] + 1]] = bc - 1; }
        }
    }
};

void compute_runs_from_lepos(const suffix_array &sa, const suffix_array &sarev, bool invlex, std::vector<std::array<size_type, 3>> &res) {
    size_type len = sa.size();
    std::vector<size_type> lepos(len);
    std::vector<size_type> stk;
    stk.reserve(len + 1);
    stk.push_back(len);
    for(size_type i = len; i--;) {
        while(stk.size() > 1) {
            size_type pos2 = stk.back();
            if(!invlex) {
                if(sa.rank(i) > sa.rank(pos2)) { break; }
            } else {
                size_type len2 = stk.end()[-2] - pos2;
                int cmp = sa.compsub(i, pos2 - i, pos2, len2);
                if(cmp != -1 && cmp != 2) { break; }
            }
            stk.pop_back();
        }
        lepos[i] = stk.back();
        stk.push_back(i);
    }

    for(size_type i = 0; i < len; ++i) {
        size_type per = lepos[i] - i;
        size_type extr = sa.lcp(i, lepos[i]);
        // choose rightmost Lyndon root (distinct)
        if(extr >= per) { continue; }
        if(invlex && lepos[i] + extr == len) { continue; }
        size_type extl = sarev.lcp(len - i, len - lepos[i]);
        if(extl + extr >= per) { res.push_back({{i - extl, lepos[i] + extr, per}}); }
    }
}

template <class RII> std::vector<std::array<size_type, 3>> compute_runs(RII beg, RII en) {
    suffix_array sa(beg, en);
    std::reverse_iterator<RII> rbeg(en), ren(beg);
    suffix_array sarev(rbeg, ren);

    size_type len = sa.size();
    std::vector<std::array<size_type, 3>> runs1;
    runs1.reserve(len);
    compute_runs_from_lepos(sa, sarev, false, runs1);
    compute_runs_from_lepos(sa, sarev, true, runs1);

    return runs1;
}
int buf[200010];

int main() {
    int len;
    cin >> len;
    for(int i = 0; i < len; ++i) cin >> buf[i];

    auto runs1 = compute_runs(buf, buf + len);
    size_type sz = runs1.size();
    std::vector<std::array<size_type, 3>> runs2(sz);
    std::vector<size_type> cnt;
    for(int i = 1; i <= 2; ++i) {
        cnt.assign(len + 2, 0);
        for(const auto &ar : runs1) { ++cnt[ar[i] + 1]; }
        std::partial_sum(cnt.begin(), cnt.end(), cnt.begin());
        for(const auto &ar : runs1) { runs2[cnt[ar[i]]++] = ar; }
        runs1.swap(runs2);
    }
    long long n = len;
    long long ans = (long long)n * (n + 1) / 2;
    using ll = long long;
    for(const auto &a : runs1) {
        ll l = a[1] - a[0];
        for(ll s = a[2] * 2; s <= l; s += a[2]) { ans += (l + 1 - s) * (s / a[2] - 1); }
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 130
memory_kb: 17332
final_rank: 2

code_snippet: #include <iostream>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cassert>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <string>
#include <algorithm>
#include <utility>
#define llint long long
#define inf 1e18
#define rep(x, s, t) for(llint (x) = (s); (x) < (t); (x)++)
#define Rep(x, s, t) for(llint (x) = (s); (x) <= (t); (x)++)
#define chmin(x, y) (x) = min((x), (y))
#define chmax(x, y) (x) = max((x), (y))
#define mod 1000000007

using namespace std;
typedef pair<llint, llint> P;
typedef pair<P, llint> Run;

void z_algorithm(vector<llint> &s, vector<llint> &z)
{
	z.resize(s.size());
	z[0] = s.size();
	
	int x = 0, y = 0;
	for(int i = 1; i < s.size(); i++){
		if(i > y){
			z[i] = 0;
			for(int j = 0; j < s.size(); j++){
				if(i+j >= s.size() || s[i+j] != s[j]) break;
				z[i]++;
			}
			x = i, y = i + z[i] - 1;
		}
		else if(i + z[i-x] <= y) z[i] = z[i-x];
		else{
			z[i] = y-i+1;
			for(int j = y-i+1; j < s.size(); j++){
				if(i+j >= s.size() || s[i+j] != s[j]) break;
				z[i]++;
			}
			x = i, y = i + z[i] - 1;
		}
	}
}

llint n;
vector<llint> s;

vector<Run> runvec;
void runget(vector<llint> &s, llint m, vector<Run> &dest)
{
	vector<llint> vec, vec2;
	vector<llint> z, z2;
	
	for(int i = m; i >= 0; i--) vec.push_back(s[i]);
	z_algorithm(vec, z);
	
	for(int i = m+1; i < s.size(); i++) vec2.push_back(s[i]);
	vec2.push_back(-1); //
	for(int i = 0; i < s.size(); i++) vec2.push_back(s[i]);
	z_algorithm(vec2, z2);
	
	dest.clear();
	llint len = s.size();
	for(int i = m; i >= 0; i--){
		llint l = 0;
		if(0 < i) l = z[m-i+1];
		llint r = z2[(len-1-m)+1+i];
		if(l+r >= m-i+1) dest.push_back(Run(P(i-l, m+r), m-i+1));
	}
}

void runcalc(vector<llint> &s, llint l, llint r)
{
	if(r-l+1 <= 1) return;
	
	llint m = (l+r)/2;
	
	vector<llint> t;
	for(int i = l; i <= r; i++) t.push_back(s[i]);
	
	vector<Run> vec;
	runget(t, m-l, vec);
	for(int i = 0; i < vec.size(); i++){
		vec[i].first.first += l;
		vec[i].first.second += l;
		runvec.push_back(vec[i]);
	}
	
	reverse(t.begin(), t.end());
	runget(t, r-(m+1), vec);
	for(int i = 0; i < vec.size(); i++){
		vec[i].first.first = r-vec[i].first.first;
		vec[i].first.second = r-vec[i].first.second;
		swap(vec[i].first.first, vec[i].first.second);
		runvec.push_back(vec[i]);
	}
	
	runcalc(s, l, m);
	runcalc(s, m+1, r);
}

void RunEnumerate(vector<llint> s, vector<Run> &dest)
{
	runvec.clear();
	runcalc(s, 0, (int)s.size()-1);
	sort(runvec.begin(), runvec.end());
	
	for(int i = 0; i < runvec.size(); i++){
		llint l = runvec[i].first.first, r = runvec[i].first.second, p = runvec[i].second;
		if(l-1 >= 0 && s[l-1+p] == s[l-1]) continue;
		if(r+1 < s.size() && s[r+1-p] == s[r+1]) continue;
		dest.push_back(Run(P(l, r), p));
	}
	runvec = dest;
	
	dest.clear();
	P p = P(-1, -1);
	for(int i = 0; i < runvec.size(); i++){
		if(runvec[i].first != p) dest.push_back(runvec[i]);
		p = runvec[i].first;
	}
}

llint get(llint x)
{
	return (x*(x+1)/2 + x*(x+1)*(2*x+1)/6) / 2;
}

int main(void)
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n;
	llint a;
	for(int i = 0; i < n; i++){
		cin >> a;
		s.push_back(a);
	}
	
	vector<Run> vec;
	RunEnumerate(s, vec);
	
	llint ans = n*(n+1)/2;
	for(int i = 0; i < vec.size(); i++){
		llint l = vec[i].first.second-vec[i].first.first+1, p = vec[i].second, m = l / p;
		ans += m*(m+1)/2*(p+l+1) - m*(m+1)*(2*m+1)/6*p - m*(l+1);
	}
	cout << ans << endl;
	
	return 0;
}
accuracy: 1
time_ms: 500
memory_kb: 122344
final_rank: 13

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }

const int max_n = 1 << 19;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

void Z_algorithm(const vector<int>& s, vector<int>& a) {
	int sz = s.size();
	a.resize(sz);
	a[0] = sz;
	int i = 1, j = 0;
	while (i < sz) {
		while (i + j < sz && s[j] == s[i + j])++j;
		a[i] = j;
		if (j == 0) { ++i; continue; }
		int k = 1;
		while (i + k < sz && k + a[k] < j)a[i + k] = a[k], ++k;
		i += k; j -= k;
	}
}
vector<int> subvec(const vector<int>& s, int le, int len) {
	vector<int> res;
	rep(j, len) {
		res.push_back(s[le + j]);
	}
	return res;
}
vector<int> operator+(const vector<int>& a, const vector<int>& b) {
	vector<int> res;
	for (int id : a)res.push_back(id);
	for (int id : b)res.push_back(id);
	return res;
}
vector<pair<int, P>> run_enumerate(vector<int>& s) {
	int n = s.size();
	s.push_back(-1);
	vector<P> v;
	vector<pair<P, int>> anss;

	function<void(int, int)> dfs = [&](int l, int r) {
		if (l + 1 == r)return;
		int m = (l + r) / 2;
		dfs(l, m); dfs(m, r);
		vector<int> le = subvec(s,l, m - l);
		reverse(all(le));
		vector<int> vl;
		Z_algorithm(le, vl); vl.push_back(0);
		vector<int> ri = subvec(s,m, r - m) + subvec(s,l, r - l);
		vector<int> vr;
		Z_algorithm(ri, vr);

		for (int c = 1; c <= m - l; c++) {
			int num = vl[c];
			num += min(vr[r - l - c], r - m);
			if (num >= c) {
				int le = m - c - vl[c];
				int ri = m + min(vr[r - l - c], r - m);
				bool valid = true;
				if (le > 0 && s[le - 1] == s[le - 1 + c])valid = false;
				if (s[ri] == s[ri - c])valid = false;
				if (valid) {
					anss.push_back({ { le,ri },c });
				}
			}
		}

		ri = subvec(s,m, r - m);
		Z_algorithm(ri, vr); vr.push_back(0);
		le = subvec(s,l, m - l); reverse(all(le));
		{
			vector<int> cop = subvec(s,l, r - l); reverse(all(cop)); le =le+ cop;
		}
		Z_algorithm(le, vl);
		for (int c = 1; c <= r - m; c++) {
			int le = m - min(vl[r - l - c], m - l);
			int ri = m + c + vr[c];
			if (ri - le >= 2 * c) {
				bool valid = true;
				if (le > 0 && s[le - 1] == s[le - 1 + c])valid = false;
				if (s[ri] == s[ri - c])valid = false;
				if (valid) {
					anss.push_back({ { le,ri },c });
				}
			}
		}
	};
	dfs(0, n);
	sort(all(anss));
	vector<pair<int, P>> ans;
	rep(i, anss.size()) {
		if (i > 0 && anss[i].first == anss[i - 1].first)continue;
		ans.push_back({ anss[i].second,anss[i].first });
	}
	sort(all(ans));
	return ans;
}

ll memo[1 << 18];
void init() {
	for (ll i = 1; i < (1 << 18); i++) {
		memo[i] = i * i * (i - 1) / 2 - (i - 1) * i * (2 * i - 1) / 6;
	}
}
void solve(){
	init();
	int n; cin >> n;
	vector<int> a(n);
	rep(i, n)cin >> a[i];
	vector<pair<int, P>> v = run_enumerate(a);
	ll ans = (ll)n * (n + 1) / 2;
	for (pair<int, P> p : v) {
		int x = p.first;
		int len = p.second.second - p.second.first;
		ll d = len / x;
		ll r = len % x;

		ans += (r + 1) * memo[d];
		r = x - 1 - r;
		ans += r * memo[d - 1];
	}
	cout << ans << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(15);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 390
memory_kb: 25460
final_rank: 10

code_snippet: //#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using db = double;
using ld = long double;
template<typename T> using V = vector<T>;
template<typename T> using VV = vector<vector<T>>;
#define fs first
#define sc second
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound
#define all(v) (v).begin(),(v).end()
#define siz(v) (ll)(v).size()
#define rep(i,a,n) for(ll i=a;i<(ll)(n);++i)
#define repr(i,a,n) for(ll i=n-1;(ll)a<=i;--i)
#define ENDL '\n'
typedef pair<int,int> Pi;
typedef pair<ll,ll> PL;
constexpr ll mod = 1000000007; // 998244353;
constexpr ll INF = 1000000099;
constexpr ll LINF = (ll)(1e18 +99);
const ld PI = acos((ld)-1);
const vector<ll> dx={-1,1,0,0},dy={0,0,-1,1};
template<typename T,typename U> inline bool chmin(T& t, const U& u){if(t>u){t=u;return 1;}return 0;}
template<typename T,typename U> inline bool chmax(T& t, const U& u){if(t<u){t=u;return 1;}return 0;}
template<typename T> inline T gcd(T a,T b){return b?gcd(b,a%b):a;}

template<typename T,typename Y> inline T mpow(T a, Y n) {
  T res = 1;
  for(;n;n>>=1) {
    if (n & 1) res = res * a;
    a = a * a;
  }
  return res;
}

template <typename T> V<T> prefix_sum(const V<T>& v) {
  int n = v.size();
  V<T> ret(n + 1);
  rep(i, 0, n) ret[i + 1] = ret[i] + v[i];
  return ret;
}

template<typename T>
istream& operator >> (istream& is, vector<T>& vec){
  for(auto&& x: vec) is >> x;
  return is;
}

template<typename T,typename Y>
ostream& operator<<(ostream& os,const pair<T,Y>& p){
  return os<<"{"<<p.fs<<","<<p.sc<<"}";
}

template<typename T> ostream& operator<<(ostream& os,const V<T>& v){
  os<<"{";
  for(auto e:v)os<<e<<",";
  return os<<"}";
}

template<typename ...Args>
void debug(Args&... args){
  for(auto const& x:{args...}){
    cerr<<x<<' ';
  }
  cerr<<ENDL;
}


template <typename T> vector<int> Zalgo(const T& s) {
  int n = (int)s.size();
  vector<int> res(n, 0);
  res[0] = 0;
  int j = 1;
  for(int i = 1; i < n; ++i) {
    if(j + res[j] <= i) {
      res[i] = 0;
    } else {
      res[i] = min(res[j] - i + j, res[i - j]);
    }
    while(i + res[i] < n && s[i + res[i]] == s[res[i]]) { ++res[i]; }
    if(j + res[j] < i + res[i]) j = i;
  }
  res[0] = n;
  return res;
}

struct RunEnum {
  int n;
  V<int> s;
  VV<Pi> runs;

  V<int> getrev(V<int> v) {
    reverse(all(v));
    return v;
  }

  V<int> getsub(int l, int r) { return {s.begin() + l, s.begin() + r}; }
  //[l,r)

  V<int> concat(V<int> l, const V<int>& r) {
    l.insert(l.end(), r.begin(), r.end());
    return l;
  }

  void run(int l, int r, int cen) {
    if(l + 1 >= r) return;
    int mid = (l + r + cen) / 2;
    run(l, mid, cen);
    run(mid, r, cen);

    V<int> z1 = Zalgo(getrev(getsub(l, mid)));
    V<int> z2 = Zalgo(concat(getsub(mid, r), getsub(l, r)));
    z1.eb(0);
    z2.eb(0);

    rep(i, l, mid) {
      int k1 = min((int)i - l, z1[mid - i]);
      int k2 = min(r - mid, z2[(r - mid) + (i - l)]);
      int pe = mid - i;
      int le = i - k1, ri = mid + k2;
      if(ri - le >= 2 * pe) runs[mid - i].eb(le, ri);
    }
  }

  template <class S> RunEnum(S _s) {
    s = {_s.begin(), _s.end()};
    n = s.size();
    runs.resize(n / 2 + 1);

    reverse(all(s));
    run(0, n, 0);
    for(auto&& run : runs) {
      for(auto&& i : run) { tie(i.fs, i.sc) = mp(n - i.sc, n - i.fs); }
    }
    reverse(all(s));
    run(0, n, 1);

    
    V<Pi> res(0);
    set<Pi> se;
    for(auto&& run:runs){
      sort(all(run),[&](Pi l,Pi r){
        if(l.fs==r.fs)return l.sc>r.sc;
        return l<r;
      });

      int mx=-1;
      for(auto&& r:run){
        if(r.sc<=mx)continue;
        chmax(mx,r.sc);

        if(se.count(r))continue;
        se.insert(r);        

        res.eb(r);
      }
      run=res;
      res.clear();
    }
    
  }
  // enumetate runs
};


signed main(){
  cin.tie(0);cerr.tie(0);ios::sync_with_stdio(false);
  cout<<fixed<<setprecision(20);
  ll n;cin>>n;
  V<ll> v(n);
  rep(i,0,n)cin>>v[i];

  RunEnum r(v);

  ll ans=n*(n+1)/2;//c==0
  rep(i, 1, siz(r.runs)) {
    for(auto&& run : r.runs[i]) {
      ll x=ll(run.sc-run.fs)/i;
      ans+=((run.sc-run.fs)%i +1)*x*(x*x-1)/6;
      ans+=(i-(run.sc-run.fs)%i -1)*(x-1)*((x-1)*(x-1)-1)/6;
    }
  }
  cout<<ans<<ENDL;
}
//! ( . _ . ) ! 
//CHECK overflow,vector_size,what to output?
accuracy: 1
time_ms: 350
memory_kb: 45860
final_rank: 11

code_snippet: //#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using db = double;
using ld = long double;
template<typename T> using V = vector<T>;
template<typename T> using VV = vector<vector<T>>;
#define fs first
#define sc second
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound
#define all(v) (v).begin(),(v).end()
#define siz(v) (ll)(v).size()
#define rep(i,a,n) for(ll i=a;i<(ll)(n);++i)
#define repr(i,a,n) for(ll i=n-1;(ll)a<=i;--i)
#define ENDL '\n'
typedef pair<int,int> Pi;
typedef pair<ll,ll> PL;
constexpr ll mod = 1000000007; // 998244353;
constexpr ll INF = 1000000099;
constexpr ll LINF = (ll)(1e18 +99);
const ld PI = acos((ld)-1);
const vector<ll> dx={-1,1,0,0},dy={0,0,-1,1};
template<typename T,typename U> inline bool chmin(T& t, const U& u){if(t>u){t=u;return 1;}return 0;}
template<typename T,typename U> inline bool chmax(T& t, const U& u){if(t<u){t=u;return 1;}return 0;}
template<typename T> inline T gcd(T a,T b){return b?gcd(b,a%b):a;}

template<typename T,typename Y> inline T mpow(T a, Y n) {
  T res = 1;
  for(;n;n>>=1) {
    if (n & 1) res = res * a;
    a = a * a;
  }
  return res;
}

template <typename T> V<T> prefix_sum(const V<T>& v) {
  int n = v.size();
  V<T> ret(n + 1);
  rep(i, 0, n) ret[i + 1] = ret[i] + v[i];
  return ret;
}

template<typename T>
istream& operator >> (istream& is, vector<T>& vec){
  for(auto&& x: vec) is >> x;
  return is;
}

template<typename T,typename Y>
ostream& operator<<(ostream& os,const pair<T,Y>& p){
  return os<<"{"<<p.fs<<","<<p.sc<<"}";
}

template<typename T> ostream& operator<<(ostream& os,const V<T>& v){
  os<<"{";
  for(auto e:v)os<<e<<",";
  return os<<"}";
}

template<typename ...Args>
void debug(Args&... args){
  for(auto const& x:{args...}){
    cerr<<x<<' ';
  }
  cerr<<ENDL;
}


template <typename T> vector<int> Zalgo(const T& s) {
  int n = (int)s.size();
  vector<int> res(n, 0);
  res[0] = 0;
  int j = 1;
  for(int i = 1; i < n; ++i) {
    if(j + res[j] <= i) {
      res[i] = 0;
    } else {
      res[i] = min(res[j] - i + j, res[i - j]);
    }
    while(i + res[i] < n && s[i + res[i]] == s[res[i]]) { ++res[i]; }
    if(j + res[j] < i + res[i]) j = i;
  }
  res[0] = n;
  return res;
}

struct RunEnum {
  int n;
  V<int> s;
  VV<Pi> runs;

  V<int> getrev(V<int> v) {
    reverse(all(v));
    return v;
  }

  V<int> getsub(int l, int r) { return {s.begin() + l, s.begin() + r}; }
  //[l,r)

  V<int> concat(V<int> l, const V<int>& r) {
    l.insert(l.end(), r.begin(), r.end());
    return l;
  }

  void run(int l, int r, int cen) {
    if(l + 1 >= r) return;
    int mid = (l + r + cen) / 2;
    run(l, mid, cen);
    run(mid, r, cen);

    V<int> z1 = Zalgo(getrev(getsub(l, mid)));
    V<int> z2 = Zalgo(concat(getsub(mid, r), getsub(l, r)));
    z1.eb(0);
    z2.eb(0);

    rep(i, l, mid) {
      int k1 = min((int)i - l, z1[mid - i]);
      int k2 = min(r - mid, z2[(r - mid) + (i - l)]);
      int pe = mid - i;
      int le = i - k1, ri = mid + k2;
      if(ri - le >= 2 * pe) runs[mid - i].eb(le, ri);
    }
  }

  template <class S> RunEnum(S _s) {
    s = {_s.begin(), _s.end()};
    n = s.size();
    runs.resize(n / 2 + 1);

    reverse(all(s));
    run(0, n, 0);
    for(auto&& run : runs) {
      for(auto&& i : run) { tie(i.fs, i.sc) = mp(n - i.sc, n - i.fs); }
    }
    reverse(all(s));
    run(0, n, 1);

    
    V<Pi> res(0);
    set<Pi> se;
    for(auto&& run:runs){
      sort(all(run),[&](Pi l,Pi r){
        if(l.fs==r.fs)return l.sc>r.sc;
        return l<r;
      });

      int mx=-1;
      for(auto&& r:run){
        if(r.sc<=mx)continue;
        chmax(mx,r.sc);

        if(se.count(r))continue;
        se.insert(r);        

        res.eb(r);
      }
      run=res;
      res.clear();
    }
    
  }
  // enumetate runs
};


signed main(){
  cin.tie(0);cerr.tie(0);ios::sync_with_stdio(false);
  cout<<fixed<<setprecision(20);
  ll n;cin>>n;
  V<ll> v(n);
  rep(i,0,n)cin>>v[i];

  RunEnum r(v);

  ll ans=n*(n+1)/2;//c==0
  rep(i, 1, siz(r.runs)) {
    for(auto&& run : r.runs[i]) {
      ll x=ll(run.sc-run.fs)/i;
      ans+=((run.sc-run.fs)%i +1)*x*(x*x-1)/6;
    }
  }
  cout<<ans<<ENDL;
}
//! ( . _ . ) ! 
//CHECK overflow,vector_size,what to output?
accuracy: 0.375
time_ms: 350
memory_kb: 45680
final_rank: 14

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<tuple>
#include<cassert>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (ll)1000000007 * 1000000007;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define Per(i,sta,n) for(int i=n-1;i>=sta;i--)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
typedef long double ld;
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<ll, ll> LP;
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
template<class T>bool chmax(T &a, const T &b) {if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T &a, const T &b) {if(b<a){a=b;return 1;}return 0;}

template<typename T>
vector<int> zalgorithm(vector<T> vs){
  int n=vs.size();
  vector<int> as(n+1,0);
  as[0]=n;
  int i=1,j=0;
  while(i<n){
    while(i+j<n&&vs[j]==vs[i+j]) j++;
    as[i]=j;
    if(j==0){
      i++;
      continue;
    }
    int k=1;
    while(i+k<n&&k+as[k]<j) as[i+k]=as[k],k++;
    i+=k;
    j-=k;
  }
  return as;
}
vector<int> zalgorithm(string s){
  return zalgorithm(vector<char>(s.begin(),s.end()));
}

namespace Run{
  using T = tuple<int, int, int>;
  using P = pair<int, int>;
  vector<vector<P>> run;

  template<typename C>
  vector<T> sub(const vector<C> &xs,const vector<C> &ys){
    auto ps=xs;
    auto qs=ys;
    reverse(ps.begin(),ps.end());
    qs.insert(qs.end(),xs.begin(),xs.end());
    qs.insert(qs.end(),ys.begin(),ys.end());
    auto zp=zalgorithm(ps);
    auto zq=zalgorithm(qs);
    vector<T> res;
    for(int i=0;i<(int)xs.size();i++){
      int a=xs.size()-i;
      int b=i-zp[a];
      int c=max(0,(int)ys.size()-zq[ys.size()+i]);
      if((int)(xs.size()+ys.size())-b-c>=2*a)
        res.emplace_back(a,b,c);
    }
    return res;
  }

  template<typename C>
  void dfs(int l,int r,const vector<C> &cs){
    if(l+1>=r) return;
    int m=(l+r)>>1;
    vector<C> xs(cs.begin()+l,cs.begin()+m);
    vector<C> ys(cs.begin()+m,cs.begin()+r);
    {
      auto zs=sub(xs,ys);
      for(auto w:zs){
        int a,b,c;
        tie(a,b,c)=w;
        run[a].emplace_back(l+b,r-c);
      }
    }
    reverse(xs.begin(),xs.end());
    reverse(ys.begin(),ys.end());
    {
      auto zs=sub(ys,xs);
      for(auto w:zs){
        int a,b,c;
        tie(a,b,c)=w;
        run[a].emplace_back(l+c,r-b);
      }
    }
    dfs(l,m,cs);
    dfs(m,r,cs);
  }

  // return all t (not only minimal)
  template<typename C>
  vector<vector<P>> enumerate(const vector<C> &cs){
    int n=cs.size();
    run.clear();
    run.resize(n+1);
    dfs(0,n,cs);

    auto cmp=[&](P a,P b){return P(a.first,-a.second)<P(b.first,-b.second);};
    for(int i=1;i<=n;i++){
      auto &rs=run[i];
      sort(rs.begin(),rs.end(),cmp);
      int mx=-1;
      vector<P> tmp;
      for(auto p:rs){
        if(mx<p.second){
          tmp.emplace_back(p);
          mx=p.second;
        }
      }
      rs=tmp;
    }
    return run;
  }

  vector<vector<P>> enumerate(string ss){
    return enumerate(vector<char>(ss.begin(),ss.end()));
  }
};

int n;
vector<int> S;
map<P,int> ma;

ll f(ll T,ll l){
  if(T<=0) return 0;
  ll d=l/T,r=l%T;
  ll res=0;
  res+=T*(d-1)*d*(2*d-1)/12;
  res-=T*d*(d-1)/4;
  res+=(r+1)*d*(d-1)/2;
  return res;
}

void solve(){
  cin >> n;S.resize(n);
  rep(i,n) cin >> S[i];
  vector<vector<P>> v=Run::enumerate(S);
  rep(i,v.size()){
    for(P p:v[i]){
      if(ma[p]==0)ma[p]=i;
    }
  }
  ll ans=(ll)n*(ll)(n+1)/2;
  for(auto x:ma){
    //cout << "["<< x.first.first << "," << x.first.second << ") period:" << x.second << endl;
    ans+=f(x.second,x.first.second-x.first.first);
  }
  cout << ans << endl;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(50);
    solve();
}
accuracy: 1
time_ms: 260
memory_kb: 46868
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

template <class T>
vector<int> z_algorithm(const T& s) {
  vector<int> res;
  int i = 1, j = 0, ssize = s.size();
  res.resize(s.size());
  res[0] = ssize;
  while (i < ssize) {
    while (i + j < ssize && s[j] == s[i + j]) ++j;
    res[i] = j;
    if (j == 0) {
      ++i;
      continue;
    }
    int k = 1;
    while (i + k < ssize && k + res[k] < j) res[i + k] = res[k], ++k;
    i += k, j -= k;
  }
  return res;
}

template <class T>
void run_enumerate(int l, int r, const T& s,
                   vector<vector<pair<int, int>>>& res) {
  if (r - l <= 1) return;
  int m = (l + r) >> 1;
  run_enumerate(l, m, s, res);
  run_enumerate(m, r, s, res);

  auto func = [&](bool rev = 0) {
    T t, tl, tr;
    copy(s.begin() + l, s.begin() + r, back_inserter(t));
    if (rev) {
      reverse(t.begin(), t.end());
      m = l + r - m;
    }
    int len = r - l, mlen = m - l;
    copy(t.begin(), t.begin() + mlen, back_inserter(tl));
    reverse(tl.begin(), tl.end());
    copy(t.begin() + mlen, t.end(), back_inserter(tr));
    copy(t.begin(), t.end(), back_inserter(tr));
    auto zl = z_algorithm(tl), zr = z_algorithm(tr);
    zl.push_back(0);
    for (int k = 1; k <= mlen; ++k) {
      int li = m - k - zl[k], ri = m + min(r - m, zr[len - k]);
      if (rev) {
        swap(li, ri);
        li = l + r - li;
        ri = l + r - ri;
      }
      if (ri - li < 2 * k) continue;
      if (li > 0 && s[li - 1] == s[li - 1 + k]) continue;
      if (ri < s.size() && s[ri] == s[ri - k]) continue;
      res[li].emplace_back(ri, k);
    }
  };
  func();
  func(1);
}

template <class T>
vector<vector<pair<int, int>>> run_enumerate(const T& s) {
  int len = s.size();
  vector<vector<pair<int, int>>> run(len), res(len);
  run_enumerate(0, len, s, run);
  for (int i = 0; i < len; ++i) {
    int rlen = run[i].size();
    sort(run[i].begin(), run[i].end());
    for (int j = 0; j < rlen; ++j)
      if (j == 0 || run[i][j].first != run[i][j - 1].first)
        res[i].push_back(run[i][j]);
  }
  return res;
}

long long n;
vector<int> s;

long long solve();

int main() {
  cin >> n;
  s.resize(n);
  for (auto& p : s) cin >> p;
  cout << solve() << endl;
  return 0;
}

long long solve() {
  long long res = n * (n + 1) / 2;
  auto run = run_enumerate(s);
  for (int i = 0; i < n; ++i)
    for (auto [r, t] : run[i]) {
      long long len = r - i, d = len / t;
      res += (d - 1) * d * (3 * (len + 1) - 2 * (d + 1) * t) / 6;
    }
  return res;
}
accuracy: 1
time_ms: 230
memory_kb: 24496
final_rank: 4

code_snippet: #include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <bitset>
#include <complex>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(...) ;
#else
#define debug(...) cerr << __LINE__ << " : " << #__VA_ARGS__ << " = " << _tostr(__VA_ARGS__) << endl;

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v);

template<typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}

void _tostr_rec(ostringstream &oss) {
  oss << "\b\b \b";
}

template<typename Head, typename... Tail>
void _tostr_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << head << ", ";
  _tostr_rec(oss, forward<Tail>(tail)...);
}

template<typename... T>
string _tostr(T &&... args) {
  ostringstream oss;
  int size = sizeof...(args);
  if (size > 1) oss << "{";
  _tostr_rec(oss, forward<T>(args)...);
  if (size > 1) oss << "}";
  return oss.str();
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

/* オイラーのΦ関数 */
// nと互いに素なn以下の数の個数

// power(a, phi(n)-1) * a = 1
// (gcd(a, n) = 1)

ll eulerPhi(ll n) {
  if (n <= 0) return 0;
  ll res = n;
  for (int i = 2; i * i <= n; i++) {
    if (n % i == 0) {
      res -= res / i;
      while (n % i == 0) n /= i;
    }
  }
  if (n > 1) res -= res / n;
  return res;
}

vector<ll> eulerPhiTable(int n) {
  vector<ll> phi(n + 1);
  iota(phi.begin(), phi.end(), 0);

  for (int i = 2; i <= n; i++)
    if (phi[i] == i)
      for (int j = 1; j * i <= n; j++)
        phi[i * j] -= phi[i * j] / i;

  return phi;
}

/* Rolling Hash */
// n = 9999991, 10000019, 924844033, 1012924417

struct RollingHash {
  int N, base;
  vector<ll> hash, pow;

  template<typename Type>
  RollingHash(int base, int n, Type *arr): N(n), base(base), hash(n + 1), pow(n + 1) {
    hash[0] = 0;
    pow[0] = 1;
    for (int i = 0; i < N; i++) {
      hash[i + 1] = (hash[i] + arr[i]) * base % mod;
      pow[i + 1] = pow[i] * base % mod;
    }
  }

  // get [l,r)
  ll getHash(int l, int r) {
    return (mod + hash[r] - hash[l] * pow[r - l] % mod) % mod;
  }
};

struct RollingHash2 {
  int N;
  RollingHash a, b;

  RollingHash2(int N, int *arr): N(N), a(9999991, N, arr), b(924844033, N, arr) {}

  ll getHash(int l, int r) {
    if (l < 0 || N < r) return -1;
    return a.getHash(l, r) * mod + b.getHash(l, r);
  }
};

int N, S[SIZE];
ll sum2[SIZE];

int main() {
  scanf("%d", &N);

  for (int i = 0; i < N; i++) {
    scanf("%d", S + i);
  }

  auto sum = eulerPhiTable(N + 1);
  sum[1] = 0;

  for (int i = 1; i <= N; i++) {
    sum[i] += sum[i - 1];
    sum2[i] = sum2[i - 1] + sum[i];
  }

  ll ans = 0;
  RollingHash2 rh(N, S);

  auto func = [&](int L, int R, int w) {
    int l = 0, r = w - 1;

    // L
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (L - mid >= 0 && rh.getHash(L - mid, L) == rh.getHash(L + w - mid, L + w)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    L -= l;

    l = 0;
    r = w - 1;
    // R
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (R + mid <= N && rh.getHash(R - w, R - w + mid) == rh.getHash(R, R + mid)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    R += l;

    assert(0 <= L && R <= N && L < R);

    return R - L;
  };

  for (int i = 1; i <= N; i++) {
    int l = 0;
    ll lh = rh.getHash(0, i);

    for (int j = 0; (j + 1) * i <= N; j++) {
      ll t = rh.getHash(j * i, (j + 1) * i);

      if (t != lh) {
        int L = l * i, R = j * i;

        ll w = func(L, R, i);
        ll q = w - (i - 1);
        ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
        ans += plus;
        l = j;
        lh = t;
      }
    }

    int L = l * i, R = N / i * i;
    ll w = func(L, R, i);
    ll q = w - (i - 1);
    ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
    ans += plus;

    debug(ans);
  }

  ans += (ll)N * (N + 1) / 2;

  printf("%lld\n", ans);

  return 0;
}
accuracy: 1
time_ms: 430
memory_kb: 13420
final_rank: 9

code_snippet: #include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <bitset>
#include <complex>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(...) ;
#else
#define debug(...) cerr << __LINE__ << " : " << #__VA_ARGS__ << " = " << _tostr(__VA_ARGS__) << endl;

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v);

template<typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}

void _tostr_rec(ostringstream &oss) {
  oss << "\b\b \b";
}

template<typename Head, typename... Tail>
void _tostr_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << head << ", ";
  _tostr_rec(oss, forward<Tail>(tail)...);
}

template<typename... T>
string _tostr(T &&... args) {
  ostringstream oss;
  int size = sizeof...(args);
  if (size > 1) oss << "{";
  _tostr_rec(oss, forward<T>(args)...);
  if (size > 1) oss << "}";
  return oss.str();
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

/* オイラーのΦ関数 */
// nと互いに素なn以下の数の個数

// power(a, phi(n)-1) * a = 1
// (gcd(a, n) = 1)

ll eulerPhi(ll n) {
  if (n <= 0) return 0;
  ll res = n;
  for (int i = 2; i * i <= n; i++) {
    if (n % i == 0) {
      res -= res / i;
      while (n % i == 0) n /= i;
    }
  }
  if (n > 1) res -= res / n;
  return res;
}

vector<int> eulerPhiTable(int n) {
  vector<int> phi(n + 1);
  iota(phi.begin(), phi.end(), 0);

  for (int i = 2; i <= n; i++)
    if (phi[i] == i)
      for (int j = 1; j * i <= n; j++)
        phi[i * j] -= phi[i * j] / i;

  return phi;
}

/* Rolling Hash */
// n = 9999991, 10000019, 924844033, 1012924417

struct RollingHash {
  int N, base;
  vector<ll> hash, pow;

  template<typename Type>
  RollingHash(int base, int n, Type *arr): N(n), base(base), hash(n + 1), pow(n + 1) {
    hash[0] = 0;
    pow[0] = 1;
    for (int i = 0; i < N; i++) {
      hash[i + 1] = (hash[i] + arr[i]) * base % mod;
      pow[i + 1] = pow[i] * base % mod;
    }
  }

  // get [l,r)
  ll getHash(int l, int r) {
    return (mod + hash[r] - hash[l] * pow[r - l] % mod) % mod;
  }
};

struct RollingHash2 {
  int N;
  RollingHash a, b;

  RollingHash2(int N, int *arr): N(N), a(9999991, N, arr), b(924844033, N, arr) {}

  ll getHash(int l, int r) {
    if (l < 0 || N < r) return -1;
    return a.getHash(l, r) * mod + b.getHash(l, r);
  }
};

int N, S[SIZE];
ll sum2[SIZE];

int main() {
  scanf("%d", &N);

  for (int i = 0; i < N; i++) {
    scanf("%d", S + i);
  }

  auto sum = eulerPhiTable(N + 1);
  sum[1] = 0;

  for (int i = 1; i <= N; i++) {
    debug(i, sum[i]);
    sum[i] += sum[i - 1];
    sum2[i] = sum2[i - 1] + sum[i];
  }

  ll ans = 0;
  RollingHash2 rh(N, S);

  auto func = [&](int L, int R, int w) {
    int l = 0, r = w - 1;

    // L
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (L - mid >= 0 && rh.getHash(L - mid, L) == rh.getHash(L + w - mid, L + w)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    L -= l;

    l = 0;
    r = w - 1;
    // R
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (R + mid <= N && rh.getHash(R - w, R - w + mid) == rh.getHash(R, R + mid)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    R += l;

    assert(0 <= L && R <= N && L < R);

    return R - L;
  };

  for (int i = 1; i <= N; i++) {
    int l = 0;
    ll lh = rh.getHash(0, i);

    for (int j = 0; (j + 1) * i <= N; j++) {
      ll t = rh.getHash(j * i, (j + 1) * i);

      if (t != lh) {
        int L = l * i, R = j * i;

        ll w = func(L, R, i);
        ll q = w - (i - 1);
        ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
        ans += plus;
        l = j;
        lh = t;
      }
    }

    int L = l * i, R = N / i * i;
    ll w = func(L, R, i);
    ll q = w - (i - 1);
    ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
    ans += plus;

    debug(ans);
  }

  ans += (ll)N * (N + 1) / 2;

  printf("%lld\n", ans);

  return 0;
}
accuracy: 0.359375
time_ms: 370
memory_kb: 12488
final_rank: 16

code_snippet: #include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <bitset>
#include <complex>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(...) ;
#else
#define debug(...) cerr << __LINE__ << " : " << #__VA_ARGS__ << " = " << _tostr(__VA_ARGS__) << endl;

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v);

template<typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}

void _tostr_rec(ostringstream &oss) {
  oss << "\b\b \b";
}

template<typename Head, typename... Tail>
void _tostr_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << head << ", ";
  _tostr_rec(oss, forward<Tail>(tail)...);
}

template<typename... T>
string _tostr(T &&... args) {
  ostringstream oss;
  int size = sizeof...(args);
  if (size > 1) oss << "{";
  _tostr_rec(oss, forward<T>(args)...);
  if (size > 1) oss << "}";
  return oss.str();
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

/* Rolling Hash */
// n = 9999991, 10000019, 924844033, 1012924417

struct RollingHash {
  int N, base;
  vector<ll> hash, pow;

  template<typename Type>
  RollingHash(int base, int n, Type *arr): N(n), base(base), hash(n + 1), pow(n + 1) {
    hash[0] = 0;
    pow[0] = 1;
    for (int i = 0; i < N; i++) {
      hash[i + 1] = (hash[i] + arr[i]) * base % mod;
      pow[i + 1] = pow[i] * base % mod;
    }
  }

  // get [l,r)
  ll getHash(int l, int r) {
    return (mod + hash[r] - hash[l] * pow[r - l] % mod) % mod;
  }
};

struct RollingHash2 {
  int N;
  RollingHash a, b;

  RollingHash2(int N, int *arr): N(N), a(9999991, N, arr), b(924844033, N, arr) {}

  ll getHash(int l, int r) {
    if (l < 0 || N < r) return -1;
    return a.getHash(l, r) * mod + b.getHash(l, r);
  }
};

int N, S[SIZE];
ll sum[SIZE], sum2[SIZE];

int main() {
  scanf("%d", &N);
  // N = 200000;

  for (int i = 0; i < N; i++) {
    scanf("%d", S + i);
    // S[i] = rand() % 1000000000;
    // S[i] = 1;
  }

  for (int i = 1; i <= N; i++) {
    ll v = i - 1;

    for (int j = 2; j * j <= i; j++) {
      if (i % j == 0)
        v -= 1 + (j * j != i);
    }

    debug(i, v);

    sum[i] = sum[i - 1] + v;
    sum2[i] = sum2[i - 1] + sum[i];
  }

  ll ans = 0;
  RollingHash2 rh(N, S);

  auto func = [&](int L, int R, int w) {
    int l = 0, r = w - 1;

    // L
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (L - mid >= 0 && rh.getHash(L - mid, L) == rh.getHash(L + w - mid, L + w)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    L -= l;

    l = 0;
    r = w - 1;
    // R
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (R + mid <= N && rh.getHash(R - w, R - w + mid) == rh.getHash(R, R + mid)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    R += l;

    assert(0 <= L && R <= N && L < R);

    return R - L;
  };

  for (int i = 1; i <= N; i++) {
    int l = 0;
    ll lh = rh.getHash(0, i);

    for (int j = 0; (j + 1) * i <= N; j++) {
      ll t = rh.getHash(j * i, (j + 1) * i);

      if (t != lh) {
        int L = l * i, R = j * i;

        ll w = func(L, R, i);
        ll q = w - (i - 1);
        ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
        ans += plus;
        l = j;
        lh = t;
      }
    }

    int L = l * i, R = N / i * i;
    ll w = func(L, R, i);
    ll q = w - (i - 1);
    ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
    ans += plus;

    debug(ans);
  }

  ans += (ll)N * (N + 1) / 2;

  printf("%lld\n", ans);

  return 0;
}
accuracy: 0.359375
time_ms: 470
memory_kb: 13164
final_rank: 17

code_snippet: #include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <bitset>
#include <complex>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(...) ;
#else
#define debug(...) cerr << __LINE__ << " : " << #__VA_ARGS__ << " = " << _tostr(__VA_ARGS__) << endl;

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v);

template<typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}

void _tostr_rec(ostringstream &oss) {
  oss << "\b\b \b";
}

template<typename Head, typename... Tail>
void _tostr_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << head << ", ";
  _tostr_rec(oss, forward<Tail>(tail)...);
}

template<typename... T>
string _tostr(T &&... args) {
  ostringstream oss;
  int size = sizeof...(args);
  if (size > 1) oss << "{";
  _tostr_rec(oss, forward<T>(args)...);
  if (size > 1) oss << "}";
  return oss.str();
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

/* Rolling Hash */
// n = 9999991, 10000019, 924844033, 1012924417

struct RollingHash {
  int N, base;
  vector<ll> hash, pow;

  template<typename Type>
  RollingHash(int base, int n, Type *arr): N(n), base(base), hash(n + 1), pow(n + 1) {
    hash[0] = 0;
    pow[0] = 1;
    for (int i = 0; i < N; i++) {
      hash[i + 1] = (hash[i] + arr[i]) * base % mod;
      pow[i + 1] = pow[i] * base % mod;
    }
  }

  // get [l,r)
  ll getHash(int l, int r) {
    return (mod + hash[r] - hash[l] * pow[r - l] % mod) % mod;
  }
};

struct RollingHash2 {
  int N;
  RollingHash a, b;

  RollingHash2(int N, int *arr): N(N), a(9999991, N, arr), b(924844033, N, arr) {}

  ll getHash(int l, int r) {
    if (l < 0 || N < r) return -1;
    return a.getHash(l, r) * mod + b.getHash(l, r);
  }
};

int N, S[SIZE];
ll sum[SIZE], sum2[SIZE];

int main() {
  scanf("%d", &N);
  // N = 200000;

  for (int i = 0; i < N; i++) {
    scanf("%d", S + i);
    // S[i] = rand() % 1000000000;
    // S[i] = 1;
  }

  for (int i = 1; i <= N; i++) {
    ll v = i - 1;

    for (int j = 2; j * j <= i; j++) {
      if (i % j == 0)
        v -= 1 + (j * j != i);
    }

    debug(i, v);

    sum[i] = sum[i - 1] + v;
    sum2[i] = sum2[i - 1] + sum[i];
  }

  ll ans = 0;
  RollingHash2 rh(N, S);

  auto func = [&](int L, int R, int w) {
    int l = 0, r = w - 1;

    // L
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (L - mid >= 0 && rh.getHash(L - mid, L) == rh.getHash(L + w - mid, L + w)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    L -= l;

    l = 0;
    r = w - 1;
    // R
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (R + mid <= N && rh.getHash(R - w, R - w + mid) == rh.getHash(R, R + mid)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    R += l;

    return R - L;
  };

  for (int i = 1; i <= N; i++) {
    int l = 0;
    ll lh = rh.getHash(0, i);

    for (int j = 0; (j + 1) * i <= N; j++) {
      ll t = rh.getHash(j * i, (j + 1) * i);

      if (t != lh) {
        int L = l * i, R = j * i;

        ll w = func(L, R, i);
        ll q = w - (i - 1);
        ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
        ans += plus;
        l = j;
        lh = t;
      }
    }

    int L = l * i, R = N / i * i;
    ll w = func(L, R, i);
    ll q = w - (i - 1);
    ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
    ans += plus;

    debug(ans);
  }

  ans += (ll)N * (N + 1) / 2;

  printf("%lld\n", ans);

  return 0;
}
accuracy: 0.359375
time_ms: 500
memory_kb: 13248
final_rank: 19

code_snippet: #include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <bitset>
#include <complex>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(...) ;
#else
#define debug(...) cerr << __LINE__ << " : " << #__VA_ARGS__ << " = " << _tostr(__VA_ARGS__) << endl;

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v);

template<typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}

void _tostr_rec(ostringstream &oss) {
  oss << "\b\b \b";
}

template<typename Head, typename... Tail>
void _tostr_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << head << ", ";
  _tostr_rec(oss, forward<Tail>(tail)...);
}

template<typename... T>
string _tostr(T &&... args) {
  ostringstream oss;
  int size = sizeof...(args);
  if (size > 1) oss << "{";
  _tostr_rec(oss, forward<T>(args)...);
  if (size > 1) oss << "}";
  return oss.str();
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

/* Rolling Hash */
// n = 9999991, 10000019, 924844033, 1012924417

struct RollingHash {
  int N, base;
  vector<ll> hash, pow;

  template<typename Type>
  RollingHash(int base, int n, Type *arr): N(n), base(base), hash(n + 1), pow(n + 1) {
    hash[0] = 0;
    pow[0] = 1;
    for (int i = 0; i < N; i++) {
      hash[i + 1] = (hash[i] + arr[i]) * base % mod;
      pow[i + 1] = pow[i] * base % mod;
    }
  }

  // get [l,r)
  ll getHash(int l, int r) {
    return (mod + hash[r] - hash[l] * pow[r - l] % mod) % mod;
  }
};

struct RollingHash2 {
  int N;
  RollingHash a, b;

  RollingHash2(int N, int *arr): N(N), a(9999991, N, arr), b(10000019, N, arr) {}

  ll getHash(int l, int r) {
    if (l < 0 || N < r) return -1;
    return a.getHash(l, r) * mod + b.getHash(l, r);
  }
};

int N, S[SIZE];
ll sum[SIZE], sum2[SIZE];

int main() {
  scanf("%d", &N);
  // N = 200000;

  for (int i = 0; i < N; i++) {
    scanf("%d", S + i);
    // S[i] = rand() % 1000000000;
    // S[i] = 1;
  }

  for (int i = 1; i <= N; i++) {
    ll v = i - 1;

    for (int j = 2; j * j <= i; j++) {
      if (i % j == 0)
        v -= 1 + (j * j != i);
    }

    debug(i, v);

    sum[i] = sum[i - 1] + v;
    sum2[i] = sum2[i - 1] + sum[i];
  }

  ll ans = 0;
  RollingHash2 rh(N, S);

  auto func = [&](int L, int R, int w) {
    int l = 0, r = w - 1;

    // L
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (L - mid >= 0 && rh.getHash(L - mid, L) == rh.getHash(L + w - mid, L + w)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    L -= l;

    l = 0;
    r = w - 1;
    // R
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (R + mid <= N && rh.getHash(R - w, R - w + mid) == rh.getHash(R, R + mid)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    R += l;

    return R - L;
  };

  for (int i = 1; i <= N; i++) {
    int l = 0;
    ll lh = rh.getHash(0, i);

    for (int j = 0; (j + 1) * i <= N; j++) {
      ll t = rh.getHash(j * i, (j + 1) * i);

      if (t != lh) {
        int L = l * i, R = j * i;

        ll w = func(L, R, i);
        ll q = w - (i - 1);
        ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
        ans += plus;
        l = j;
        lh = t;
      }
    }

    int L = l * i, R = N / i * i;
    ll w = func(L, R, i);
    ll q = w - (i - 1);
    ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
    ans += plus;

    debug(ans);
  }

  ans += (ll)N * (N + 1) / 2;

  printf("%lld\n", ans);

  return 0;
}
accuracy: 0.359375
time_ms: 510
memory_kb: 13312
final_rank: 20

code_snippet: #include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <bitset>
#include <complex>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#ifndef LOCAL
#define debug(...) ;
#else
#define debug(...) cerr << __LINE__ << " : " << #__VA_ARGS__ << " = " << _tostr(__VA_ARGS__) << endl;

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v);

template<typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &p) {
  out << "{" << p.first << ", " << p.second << "}";
  return out;
}

template<typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << '{';
  for (const T &item : v) out << item << ", ";
  out << "\b\b}";
  return out;
}

void _tostr_rec(ostringstream &oss) {
  oss << "\b\b \b";
}

template<typename Head, typename... Tail>
void _tostr_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << head << ", ";
  _tostr_rec(oss, forward<Tail>(tail)...);
}

template<typename... T>
string _tostr(T &&... args) {
  ostringstream oss;
  int size = sizeof...(args);
  if (size > 1) oss << "{";
  _tostr_rec(oss, forward<T>(args)...);
  if (size > 1) oss << "}";
  return oss.str();
}
#endif

#define mod 1000000007 //1e9+7(prime number)
#define INF 1000000000 //1e9
#define LLINF 2000000000000000000LL //2e18
#define SIZE 200010

/* Rolling Hash */
// n = 9999991, 10000019, 924844033, 1012924417

struct RollingHash {
  int N, base;
  vector<ll> hash, pow;

  template<typename Type>
  RollingHash(int base, int n, Type *arr): N(n), base(base), hash(n + 1), pow(n + 1) {
    hash[0] = 0;
    pow[0] = 1;
    for (int i = 0; i < N; i++) {
      hash[i + 1] = (hash[i] + arr[i]) * base % mod;
      pow[i + 1] = pow[i] * base % mod;
    }
  }

  // get [l,r)
  ll getHash(int l, int r) {
    return (mod + hash[r] - hash[l] * pow[r - l] % mod) % mod;
  }
};

struct RollingHash2 {
  int N;
  RollingHash a, b;

  RollingHash2(int N, int *arr): N(N), a(9999991, N, arr), b(10000019, N, arr) {}

  ll getHash(int l, int r) {
    if (l < 0 || N < r) return -1;
    return a.getHash(l, r) * mod + b.getHash(l, r);
  }
};

int N, S[SIZE];
ll sum[SIZE], sum2[SIZE];

int main() {
  scanf("%d", &N);
  // N = 200000;

  for (int i = 0; i < N; i++) {
    scanf("%d", S + i);
    // S[i] = rand() % 1000000000;
    // S[i] = 1;
  }

  for (int i = 1; i <= N; i++) {
    ll v = i - 1;

    for (int j = 2; j * j <= i; j++) {
      if (i % j == 0)
        v -= 1 + (j * j != i);
    }

    sum[i] = sum[i - 1] + v;
    sum2[i] = sum2[i - 1] + sum[i];
  }

  ll ans = 0;
  RollingHash2 rh(N, S);

  auto func = [&](int L, int R, int w) {
    int l = 0, r = w - 1;

    // L
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (L - mid >= 0 && rh.getHash(L - mid, L) == rh.getHash(L + w - mid, L + w)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    L -= l;

    l = 0;
    r = w - 1;
    // R
    while (l < r) {
      int mid = (r + l + 1) / 2;

      if (R + mid < N && rh.getHash(R - w, R - w + mid) == rh.getHash(R, R + mid)) {
        l = mid;
      } else {
        r = mid - 1;
      }
    }
    R += l;

    return R - L;
  };

  for (int i = 1; i <= N; i++) {
    int l = 0;
    ll lh = rh.getHash(0, i);

    for (int j = 0; (j + 1) * i <= N; j++) {
      ll t = rh.getHash(j * i, (j + 1) * i);

      if (t != lh) {
        int L = l * i, R = j * i;

        ll w = func(L, R, i);
        ll q = w - (i - 1);
        ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
        ans += plus;
        l = j;
        lh = t;
      }
    }

    int L = l * i, R = N / i * i;
    ll w = func(L, R, i);
    ll q = w - (i - 1);
    ll plus = sum2[q / i] * i + (q % i) * sum[(q + i - 1) / i];
    ans += plus;

    debug(ans);
  }

  ans += (ll)N * (N + 1) / 2;

  printf("%lld\n", ans);

  return 0;
}
accuracy: 0.359375
time_ms: 500
memory_kb: 13164
final_rank: 18

code_snippet: #include <bits/stdc++.h>

using namespace std;

using i64 = long long;

const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;


template <typename T>
bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}

template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

template <class S> V<int> z_algo(const S& s) {
    int n = int(s.size());
    V<int> r(n + 1);
    r[0] = 0;
    for (int i = 1, j = 0; i <= n; i++) {
        int& k = r[i];
        k = (j + r[j] <= i) ? 0 : min(j + r[j] - i, r[i - j]);
        while (i + k < n && s[k] == s[i + k]) k++;
        if (j + r[j] < i + r[i]) j = i;
    }
    r[0] = n;
    return r;
}

struct RunExec {
    VV<pair<int, int>> runs;

    int n;
    V<int> a;

    V<int> rev(V<int> l) {
        reverse(l.begin(), l.end());
        return l;
    }

    V<int> sub_a(int l, int r) {
        return {a.begin() + l, a.begin() + r};
    }
    V<int> concat(V<int> l, const V<int>& r) {
        l.insert(l.end(), r.begin(), r.end());
        return l;
    }

    void run(int l, int r, int f) {
        if (l + 1 == r) return;
        int md = (l + r + f) / 2;
        run(l, md, f);
        run(md, r, f);
        auto z1 = z_algo(rev(sub_a(l, md)));
        auto z2 = z_algo(concat(sub_a(md, r), sub_a(l, r)));
        for (int i = md - 1; i >= l; i--) {
            int l1 = min(i - l, z1[md - i]);
            int l2 = min(r - md, z2[(r - l) - (md - i)]);
            int le = i - l1, ri = md + l2, peri = md - i;
            if (ri - le >= 2 * peri) runs[md - i].push_back({i - l1, md + l2});
        }
    }

    RunExec(V<int> _a) : a(_a) {
        n = int(a.size());
        runs.resize(n / 2 + 1);
        reverse(a.begin(), a.end());
        run(0, n, 0);
        for (auto& run: runs) {
            for (auto& p: run) {
                tie(p.first, p.second) =
                        make_pair(n - p.second, n - p.first);
            }
        }
        reverse(a.begin(), a.end());
        run(0, n, 1);

        set<pair<int, int>> vis;
        for (int ph = 1; ph <= n / 2; ph++) {
            auto& run = runs[ph];
            sort(run.begin(), run.end(), [&](pair<int, int> lhs, pair<int, int> rhs) {
                if (lhs.first != rhs.first) return lhs.first < rhs.first;
                return lhs.second > rhs.second;
            });
            V<pair<int, int>> res;
            for (auto p: run) {
                if (!res.empty() && p.second <= res.back().second) continue;
                res.push_back(p);
            }
            run = res;
            res.clear();
            for (auto p: run) {
                if (vis.count(p)) continue;
                vis.insert(p);
                res.push_back(p);
            }
            run = res;
        }
    }
};

i64 f(i64 k, i64 t){
    i64 res = 0;
    for(int i = 2; i * t <= k; ++i){
        res += (i - 1) * (k - i * t + 1);
    }
    return res;
}

signed main(){
    i64 n;
    cin >> n;
    vector<int> s(n);
    for(int i = 0; i < n; ++i)
        cin >> s[i];
    RunExec runexec(s);
    i64 ans = n * (n + 1) / 2;
    for(int i = 0; i < runexec.runs.size(); ++i){
        auto v = runexec.runs[i];
        sort(v.begin(), v.end());
        for(auto p : v){
            ans += f(p.second - p.first, i);
        }
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 260
memory_kb: 42912
final_rank: 6

code_snippet: #include <algorithm>
#include <array>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <numeric>
#include <string>
#include <utility>
#include <vector>
using namespace std;

typedef unsigned size_type;

#define USE_RMQ

template <class DatTp, class Comp = std::less<DatTp>> struct static_rmq {
    typedef unsigned long long ull;
    typedef unsigned size_type;

    std::vector<DatTp> data;
    Comp cmp;
    std::vector<std::vector<size_type>> sp_rmq;
    std::vector<ull> bl_tort;

    explicit static_rmq(const Comp &comp = Comp()) : cmp(comp) {}

    void init() {
        data.clear();
        sp_rmq.clear();
        bl_tort.clear();
    }

    template <class Iter> static_rmq(Iter beg, Iter en, const Comp &comp = Comp()) : cmp(comp) { init(beg, en); }

    template <class Iter> void init(Iter beg, Iter en) {
        sp_rmq.clear();
        bl_tort.clear();
        data.assign(beg, en);
        size_type sz = size();
        if(!sz) { return; }

        size_type sp_len = sz / 64;
        sp_rmq.reserve(64 - __builtin_clzll(sp_len | 1));

        std::vector<size_type> vec(sp_len);
        for(size_type i = 0; i < sp_len; ++i) {
            size_type t = i * 64;
            for(size_type j = t + 1; j < (i + 1) * 64; ++j) { t = minidx(t, j); }
            vec[i] = t;
        }
        sp_rmq.push_back(vec);

        for(size_type i = 1; (1u << i) <= sp_len; ++i) {
            vec.clear();
            size_type r = (1u << (i - 1));
            std::vector<size_type> &prv = sp_rmq.back();
            for(size_type j = 0; j + r * 2 <= sp_len; ++j) { vec.push_back(minidx(prv[j], prv[j + r])); }
            sp_rmq.push_back(vec);
        }

        bl_tort.assign(sz, 0ull);
        std::vector<size_type> st;
        st.reserve(64);
        for(size_type low = 0; low < sz; low += 64) {
            size_type high = std::min<size_type>(low + 64, sz);
            ull val = 0;
            st.clear();
            for(size_type j = high; j-- != low;) {
                while(!st.empty()) {
                    size_type tp = st.back();
                    if(cmp(data[tp], data[j])) { break; }
                    val ^= 1ull << (tp % 64);
                    st.pop_back();
                }
                st.push_back(j);
                val |= 1ull << (j % 64);
                bl_tort[j] = val;
            }
        }
    }

    size_type size() const { return data.size(); }

    size_type minidx(size_type i, size_type j) const {
        if(i > j) { std::swap(i, j); }
        // if(j >= size()){ return i; }
        return !cmp(data[j], data[i]) ? i : j;
    }

    const DatTp &operator[](size_type i) const { return data[i]; }

    // [lt, rt]
    size_type operator()(size_type lt, size_type rt) const {
        if(lt > rt) { return lt; }
        size_type bl_lt = lt / 64, bl_rt = rt / 64;
        size_type ret;
        ull rtmask = ((2ull << (rt % 64)) - 1);
        if(bl_lt == bl_rt) {
            ull bit = bl_tort[lt] & rtmask;
            size_type k = 63 - __builtin_clzll(bit);
            ret = bl_lt * 64 + k;
        } else {
            ret = bl_lt * 64 + 63 - __builtin_clzll(bl_tort[lt]);
            if(bl_lt + 1 != bl_rt) {
                size_type numblk = bl_rt - bl_lt - 1;
                size_type k = 63 - __builtin_clzll(numblk);
                size_type cand1 = sp_rmq[k][bl_lt + 1];
                ret = minidx(ret, cand1);
                if((1u << k) != numblk) {
                    size_type cand2 = sp_rmq[k][bl_rt - (1u << k)];
                    ret = minidx(ret, cand2);
                }
            }
            size_type cand3 = bl_rt * 64 + 63 - __builtin_clzll(bl_tort[bl_rt * 64] & rtmask);
            ret = minidx(ret, cand3);
        }
        return ret;
    }
};

struct suffix_array {
    typedef unsigned size_type;

    size_type size() const { return sa.size(); }

    size_type rank(size_type a) const { return rnk[a]; }

    size_type operator[](size_type x) const { return sa[x]; }

#ifdef USE_RMQ
    size_type lcp_order_adj(size_type a) const { return rmq[a]; }

    // lcp(S[a..], S[b..])
    size_type lcp(size_type a, size_type b) const {
        if(a >= size() || b >= size()) { return 0; }
        return lcp_ord(rnk[a], rnk[b]);
    }

    // [a,b] or [b,a]
    size_type lcp_ord(size_type a, size_type b) const {
        if(a == b) { return size() - sa[a]; }
        if(a > b) { std::swap(a, b); }
        size_type k = rmq(a + 1, b);
        return rmq[k];
    }

    int compsub(size_type pos1, size_type len1, size_type pos2, size_type len2) const {
        len1 = std::min(len1, size() - pos1);
        len2 = std::min(len2, size() - pos2);
        size_type com = lcp(pos1, pos2);
        com = std::min(com, std::min(len1, len2));
        if(com == len1) {
            if(com == len2) { return 0; }
            return -1;
        }
        if(com == len2) { return 1; }
        return rank(pos1) < rank(pos2) ? -2 : 2;
    }
#endif

    std::vector<size_type> sa;
    std::vector<size_type> rnk;
    std::vector<size_type> acc;
#ifdef USE_RMQ
    static_rmq<size_type> rmq;
#endif

    suffix_array() {}

    template <class Cont> explicit suffix_array(Cont &c) : suffix_array(c.begin(), c.end()) {}

    template <class RAI> suffix_array(RAI first, RAI last) { init(first, last); }

    void init() {
        sa.clear();
        rnk.clear();
        acc.clear();
#ifdef USE_RMQ
        rmq.init();
#endif
    }

    template <class Cont> void init(Cont &c) { init(c.begin(), c.end()); }

    template <class RAI> void init(RAI first, RAI last) {
        typedef typename std::iterator_traits<RAI>::value_type value_type;

        init();
        if(first == last) { return; }

        size_type len = std::distance(first, last);
        std::pair<RAI, RAI> minmax = std::minmax_element(first, last);
        if(*minmax.first < 0 || *minmax.second + size_type() > std::max<size_type>(len * 3, 250)) {
            std::vector<value_type> vec(first, last);
            std::sort(vec.begin(), vec.end());
            vec.erase(unique(vec.begin(), vec.end()), vec.end());
            std::vector<size_type> idx;
            idx.reserve(len);
            for(RAI it = first; it != last; ++it) { idx.push_back(std::lower_bound(vec.begin(), vec.end(), *it) - vec.begin()); }
            std::vector<value_type>().swap(vec);
            construct_sa_lcp(idx.begin(), idx.end());
        } else {
            construct_sa_lcp(first, last);
        }
    }

    template <class RAI> void construct_sa_lcp(RAI first, RAI last) {
        size_type kind = *std::max_element(first, last) + 1;
        size_type len = std::distance(first, last);
        acc.reserve(std::max(kind, len) + 1);
        sa = calcsa(first, last, kind);
        std::vector<size_type>().swap(acc);

        rnk.resize(len);
        for(size_type i = 0; i < len; ++i) { rnk[sa[i]] = i; }

        std::vector<size_type> lcpar(len);
        size_type h = 0;
        for(size_type i = 0; i < len; ++i) {
            if(rnk[i] == 0) {
                h = 0;
            } else {
                size_type j = sa[rnk[i] - 1];
                if(h > 0) { --h; }
                for(; j + h < len && i + h < len; ++h) {
                    if(first[j + h] != first[i + h]) { break; }
                }
            }
            lcpar[rnk[i]] = h;
        }
#ifdef USE_RMQ
        rmq.init(lcpar.begin(), lcpar.end());
#endif
    }

    void calcacc(const std::vector<size_type> &cnt) {
        acc.resize(cnt.size() + 1);
        acc[0] = 0;
        std::partial_sum(cnt.begin(), cnt.end(), acc.begin() + 1);
    }

    template <class RAI> std::vector<size_type> calcsa(RAI first, RAI last, size_type kind) {
        size_type len = std::distance(first, last);

        std::vector<size_type> cnt(kind);
        for(RAI it = first; it != last; ++it) { ++cnt[*it]; }

        std::vector<int> stype(len);
        for(size_type i = len - 1; i--;) {
            if(first[i] == first[i + 1]) {
                stype[i] = stype[i + 1];
            } else {
                stype[i] = (first[i] < first[i + 1]);
            }
        }
        std::vector<size_type> lms;
        size_type numlms = 0;
        std::vector<size_type> ridx(len, size_type(-1));

        std::vector<size_type> bucket(len, size_type(-1));
        calcacc(cnt);
        for(size_type i = 1; i < len; ++i) {
            if(stype[i] && !stype[i - 1]) {
                stype[i] = 2;
                bucket[--acc[first[i] + 1]] = i;
                ridx[i] = numlms++;
                lms.push_back(i);
            }
        }

        induced_sort(first, last, kind, stype, cnt, bucket);

        size_type lmskind = size_type(-1);
        std::vector<size_type> lmsstr(numlms);
        size_type prv = size_type(-1);
        for(size_type i = 0; i < len; ++i) {
            size_type r = ridx[bucket[i]];
            if(r != size_type(-1)) {
                if(prv == size_type(-1) || prv + 1 == numlms || r + 1 == numlms || lms[prv + 1] - lms[prv] != lms[r + 1] - lms[r] ||
                   !std::equal(first + lms[prv], first + (lms[prv + 1] + 1), first + lms[r])) {
                    ++lmskind;
                }
                lmsstr[r] = lmskind;
                prv = r;
            }
        }
        ++lmskind;

        std::vector<size_type> lmssa;
        if(lmskind != numlms) {
            lmssa = calcsa(lmsstr.begin(), lmsstr.end(), lmskind);
        } else {
            lmssa.resize(numlms);
            for(size_type i = 0; i < numlms; ++i) { lmssa[lmsstr[i]] = i; }
        }

        calcacc(cnt);
        bucket.assign(len, size_type(-1));
        for(size_type i = numlms; i--;) {
            size_type pos = lms[lmssa[i]];
            bucket[--acc[first[pos] + 1]] = pos;
        }
        induced_sort(first, last, kind, stype, cnt, bucket);

        return bucket;
    }

    template <class RAI>
    void induced_sort(RAI first, RAI last, size_type kind, const std::vector<int> &stype, std::vector<size_type> &cnt, std::vector<size_type> &bucket) {
        size_type len = std::distance(first, last);
        calcacc(cnt);
        bucket[acc[+first[len - 1]]++] = len - 1;
        for(size_type i = 0; i < len; ++i) {
            size_type bc = bucket[i];
            if(bc != size_type(-1) && bc != 0 && !stype[bc - 1]) { bucket[acc[+first[bc - 1]]++] = bc - 1; }
        }
        calcacc(cnt);
        for(size_type i = len; i--;) {
            size_type bc = bucket[i];
            if(bc != size_type(-1) && bc != 0 && stype[bc - 1]) { bucket[--acc[first[bc - 1] + 1]] = bc - 1; }
        }
    }
};

void compute_runs_from_lepos(const suffix_array &sa, const suffix_array &sarev, bool invlex, std::vector<std::array<size_type, 3>> &res) {
    size_type len = sa.size();
    std::vector<size_type> lepos(len);
    std::vector<size_type> stk;
    stk.reserve(len + 1);
    stk.push_back(len);
    for(size_type i = len; i--;) {
        while(stk.size() > 1) {
            size_type pos2 = stk.back();
            if(!invlex) {
                if(sa.rank(i) > sa.rank(pos2)) { break; }
            } else {
                size_type len2 = stk.end()[-2] - pos2;
                int cmp = sa.compsub(i, pos2 - i, pos2, len2);
                if(cmp != -1 && cmp != 2) { break; }
            }
            stk.pop_back();
        }
        lepos[i] = stk.back();
        stk.push_back(i);
    }

    for(size_type i = 0; i < len; ++i) {
        size_type per = lepos[i] - i;
        size_type extr = sa.lcp(i, lepos[i]);
        // choose rightmost Lyndon root (distinct)
        if(extr >= per) { continue; }
        if(invlex && lepos[i] + extr == len) { continue; }
        size_type extl = sarev.lcp(len - i, len - lepos[i]);
        if(extl + extr >= per) { res.push_back({{i - extl, lepos[i] + extr, per}}); }
    }
}

template <class RII> std::vector<std::array<size_type, 3>> compute_runs(RII beg, RII en) {
    suffix_array sa(beg, en);
    std::reverse_iterator<RII> rbeg(en), ren(beg);
    suffix_array sarev(rbeg, ren);

    size_type len = sa.size();
    std::vector<std::array<size_type, 3>> runs1;
    runs1.reserve(len);
    compute_runs_from_lepos(sa, sarev, false, runs1);
    compute_runs_from_lepos(sa, sarev, true, runs1);

    return runs1;
}
int buf[200010];

int main() {
    int len;
    cin >> len;
    for(int i = 0; i < len; ++i) cin >> buf[i];

    auto runs1 = compute_runs(buf, buf + len);
    size_type sz = runs1.size();
    std::vector<std::array<size_type, 3>> runs2(sz);
    std::vector<size_type> cnt;
    for(int i = 1; i <= 2; ++i) {
        cnt.assign(len + 2, 0);
        for(const auto &ar : runs1) { ++cnt[ar[i] + 1]; }
        std::partial_sum(cnt.begin(), cnt.end(), cnt.begin());
        for(const auto &ar : runs1) { runs2[cnt[ar[i]]++] = ar; }
        runs1.swap(runs2);
    }
    long long n = len;
    long long ans = (long long)n * (n + 1) / 2;
    using ll = long long;
    for(const auto &a : runs1) {
        ll l = a[1] - a[0];
        for(ll s = a[2] * 2; s <= l; s += a[2]) { ans += (l + 1 - s) * (s / a[2] - 1); }
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 130
memory_kb: 17296
final_rank: 1