#include namespace { #pragma GCC diagnostic ignored "-Wunused-function" #include #pragma GCC diagnostic warning "-Wunused-function" using namespace std; using namespace atcoder; #define rep(i,n) for(int i = 0; i < (int)(n); i++) #define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; i--) #define all(x) begin(x), end(x) #define rall(x) rbegin(x), rend(x) template bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } else return false; } template bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; } else return false; } using ll = long long; using P = pair; using VI = vector; using VVI = vector; using VL = vector; using VVL = vector; // e is only used as retval of empty range query template::max> struct RmQ { unsigned int n; std::vector a; std::vector> btable; std::vector ibtable; RmQ() {} explicit RmQ(std::vector a): a(move(a)), n(a.size()), ibtable(n) { preproc_block_RmQ(); preproc_in_block_RmQ(); } void preproc_block_RmQ() { if (n == 0) return; const unsigned int m = (n + 31) >> 5; // block count const unsigned int k = ceil_pow2(m); btable.resize(k + 1); for(int i = 0; i <= k; i++) btable[i].resize(m); T now = a[n - 1]; for(int i = n - 1; i >= 0; i--) { if (a[i] < now) now = a[i]; if ((i & 31) == 0) { btable[0][i >> 5] = now; if (i) { now = a[--i]; } } } for(unsigned int i = 0; i < k; i++) { unsigned int p1 = 0, p2 = 1 << i; for(; p2 < m; p1++, p2++) { T x = btable[i][p1], y = btable[i][p2]; btable[i + 1][p1] = (x < y ? x : y); } for(; p1 < m; p1++) btable[i + 1][p1] = btable[i][p1]; } } void preproc_in_block_RmQ() { const unsigned int m = (n + 31) >> 5; // block count unsigned int st[32]; for(unsigned int b = 0; b < m; b++) { unsigned int s = b << 5, t = std::min((b + 1) << 5, n); int top = -1; for(unsigned int i = s; i < t; i++) { while(top != -1 && !(a[st[top]] < a[i])) top--; unsigned int x = 1U << (i & 31); if (top != -1) x |= ibtable[st[top]]; ibtable[i] = x; st[++top] = i; } } } T operator()(int l, int r) { if (l >= r) return e(); r--; // [l, r] const unsigned int bl = l >> 5, ibl = l & 31, br = r >> 5, ibr = r & 31; if (bl == br) { return a[(bl << 5) | __builtin_ctz(ibtable[r] & (~0U << ibl))]; } else if (bl + 1 == br) { return std::min(a[bl << 5 | __builtin_ctz(ibtable[l | 31] & (~0U << ibl))], a[(br << 5) | __builtin_ctz(ibtable[r])]); } else { // [bl + 1, br) int len = br - bl - 1; int k = __lg(len); // int k = 31 - __builtin_clz(len); return std::min( std::min(btable[k][bl + 1], btable[k][br - (1 << k)]), std::min(a[bl << 5 | __builtin_ctz(ibtable[l | 31] & (~0U << ibl))], a[(br << 5) | __builtin_ctz(ibtable[r])]) ); } } // excerpt from internal_bit in ACL // @param n `0 <= n` // @return minimum non-negative `x` s.t. `n <= 2**x` int ceil_pow2(int n) { int x = 0; while ((1U << x) < (unsigned int)(n)) x++; return x; } }; } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; VI a(n); rep(i, n) cin >> a[i]; if (n == 1) { cout << 1 << '\n'; return 0; } VI b(2 * (n - 1)); rep(i, n - 1) b[i] = a[i+1] - a[i]; rep(i, n - 1) b[n-1+i] = -(a[n-1-(i+1)] - a[n-1-i]); VI sa = suffix_array(b); VI inv(2 * (n - 1)); rep(i, 2 * (n - 1)) inv[sa[i]] = i; RmQ seg(lcp_array(b, sa)); ll ans = 0; rep(i, n) { if (i == 0 || i == n - 1) { ans++; continue; } int p = inv[i], q = inv[n-1+n-1-i]; if (p > q) swap(p, q); int res = seg(p, q) + 1; chmin(res, min(i + 1, n - i)); ans += res; } rep(i, n - 1) { if (i == 0 || i == n - 2) { ans++; continue; } int p = inv[i], q = inv[n-1+n-1-(i+1)]; if (p > q) swap(p, q); int res = seg(p, q); chmin(res, min(i + 1, n - (i + 1))); ans += res; } cout << ans << '\n'; }