Pagini recente » Cod sursa (job #2581122) | Cod sursa (job #2604317) | Cod sursa (job #2520575) | Cod sursa (job #2500452) | Cod sursa (job #466798)
Cod sursa(job #466798)
#include <stdio.h>
#include <algorithm>
using namespace std;
#define MAX_N 100010
long long sol;
int st, n;
int A[MAX_N];
int diff[MAX_N];
int p2[MAX_N];
int rmq_min[17][MAX_N], rmq_max[17][MAX_N];
void expand(int i) {
while (st - 1 >= 1 && i + 1 + (i - st) + 1 <= n && A[st - 1] + A[i + 1 + (i - st) + 1] == A[i] + A[i + 1])
st--;
}
inline int query_min(int st, int dr) {
int dist = dr - st + 1;
return min(rmq_min[p2[dist]][st], rmq_min[p2[dist]][dr - (1 << p2[dist]) + 1]);
}
inline int query_max(int st, int dr) {
int dist = dr - st + 1;
return max(rmq_max[p2[dist]][st], rmq_max[p2[dist]][dr - (1 << p2[dist]) + 1]);
}
void solve(int dec) {
st = 1; sol++;
for (int i = 2; i <= n / 2 - dec; i++) {
if (st != i - 1) {
int r_min = query_min(i + 2, i + 2 + (i - st - 1));
int r_max = query_max(i + 2, i + 2 + (i - st - 1));
if (r_min != r_max) {
if (A[i - 1] + A[i + 2] != A[i] + A[i + 1])
st = i;
else {
int left = st, right = i, mid = 0, rez = i;
while (left + 1 < right) {
mid = (left + right) / 2;
r_min = query_min(i + 2, i + 2 + (i - mid - 1));
r_max = query_max(i + 2, i + 2 + (i - mid - 1));
if (r_min == r_max) {
rez = min(rez, mid);
right = mid;
}
else
left = mid;
}
st = rez;
}
}
}
else
st = i;
expand(i);
sol = sol + (i - st + 1);
}
}
int main() {
freopen("numarare.in", "r", stdin);
freopen("numarare.out", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &A[i]);
for (int i = 3; i <= n; i++) {
diff[i] = A[i] - A[i - 2];
rmq_min[0][i] = rmq_max[0][i] = diff[i];
}
for (int i = 0; i < 17; i++)
p2[1 << i] = i;
for (int i = 2; i < n; i++)
if (p2[i + 1] == 0)
p2[i + 1] = p2[i];
for (int i = 1; (1 << i) <= n; i++)
for (int j = 1; j + (1 << i) - 1 <= n; j++) {
int right = j + (1 << i) - 1;
rmq_min[i][j] = min(rmq_min[i - 1][j], rmq_min[i - 1][right - (1 << (i - 1)) + 1]);
rmq_max[i][j] = max(rmq_max[i - 1][j], rmq_max[i - 1][right - (1 << (i - 1)) + 1]);
}
solve(0);
for (int i = 1; i <= n / 2; i++)
swap(A[i], A[n + 1 - i]);
for (int i = 3; i <= n; i++)
rmq_min[0][i] = rmq_max[0][i] = A[i] - A[i - 2];
for (int i = 1; (1 << i) <= n; i++)
for (int j = 1; j + (1 << i) - 1 <= n; j++) {
int right = j + (1 << i) - 1;
rmq_min[i][j] = min(rmq_min[i - 1][j], rmq_min[i - 1][right - (1 << (i - 1)) + 1]);
rmq_max[i][j] = max(rmq_max[i - 1][j], rmq_max[i - 1][right - (1 << (i - 1)) + 1]);
}
if (n % 2 == 0)
solve(1);
else
solve(0);
printf("%lld\n", sol);
return 0;
}