Cod sursa(job #466134)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 26 iunie 2010 11:06:29
Problema Numarare Scor Ascuns
Compilator cpp Status done
Runda Marime 1.48 kb
#include <cstdio>
#include <cassert>
#include <algorithm>
#include <vector>

using namespace std;

#define MAXN 100000
#define MAXV 100000

int N, x[MAXN], first[MAXN];
vector<int> M[MAXV + 1];
int p[MAXV + 1];

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(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; 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]]];
        }

        for (int i = 0; i < N; i++) {
            int j, lim = first[i];
            for (j = i + 1; j < N; j++) {
                if (x[i] + x[j] == SUM && lim <= j) {
                    NR += 1;
                }
                if (first[j] > lim) {
                    lim = first[j];
                }
            }
        }
    }

    printf("%d\n", NR);
    return 0;
}