Pagini recente » Cod sursa (job #21110) | Cod sursa (job #1136790) | Cod sursa (job #465164) | Cod sursa (job #1181987) | Cod sursa (job #466254)
Cod sursa(job #466254)
#include <cstdio>
#include <cassert>
#include <algorithm>
#include <vector>
using namespace std;
#define MAXN 100000
#define MAXV 100000
#define MAXT 524288
int N, x[MAXN], first[MAXN];
vector<int> M[2 * MAXV + 1];
int p[2 * MAXV + 1], aint[MAXT];
#define AINTCOMMON int lc = (n << 1), rc = (lc + 1), m = (l + r) >> 1
inline void buildTree(int n, int l, int r) {
if (l == r) {
aint[n] = first[l];
return;
}
AINTCOMMON;
buildTree(lc, l, m);
buildTree(rc, m + 1, r);
aint[n] = max(aint[lc], aint[rc]);
}
int QL, QR;
inline int query(int n, int l, int r) {
if (QL <= l && r <= QR) {
return aint[n];
}
int rez = -1;
AINTCOMMON;
if (QL <= m) {
rez = max(rez, query(lc, l, m));
}
if (QR > m) {
rez = max(rez, query(rc, m + 1, r));
}
return rez;
}
int main() {
freopen("numarare.in", "rt", stdin);
#ifndef DEBUG
freopen("numarare.out", "wt", stdout);
#endif
assert(scanf("%d", &N) == 1);
assert(1 <= N && N <= MAXN);
int MIN = 0x3f3f3f3f, MAX = -0x3f3f3f3f;
for (int i = 0; i < N; i++) {
assert(scanf("%d", x + i) == 1);
assert(-MAXV <= x[i] && x[i] <= MAXV);
x[i] += MAXV;
MIN = min(MIN, x[i]);
MAX = max(MAX, x[i]);
M[x[i]].push_back(i);
}
for (int i = 0; i <= MAXV * 2; i++) {
M[i].push_back(N);
}
int NR = 0;
for (int SUM = MIN * 2; SUM <= MAX * 2; SUM++) {
for (int i = 0; i <= MAXV; i++) {
p[i] = 0;
}
for (int i = 0; i < N; i++) {
if (x[i] > SUM) {
first[i] = N;
continue;
}
for (; M[SUM - x[i]][p[SUM - x[i]]] <= i; p[SUM - x[i]] += 1);
first[i] = M[SUM - x[i]][p[SUM - x[i]]];
}
buildTree(1, 0, N - 1);
for (int i = 0; i < N; i++) {
vector<int> :: iterator it;
for (it = M[SUM - x[i]].begin(); it != M[SUM - x[i]].end(); it++) {
if (*it <= i || *it == N) {
continue;
}
if ((*it - i + 1) % 2 != 0) {
continue;
}
QL = i; QR = (i + *it) / 2;
if (query(1, 0, N - 1) <= *it) {
NR += 1;
}
}
}
}
printf("%d\n", NR);
return 0;
}