Cod sursa(job #67498)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 25 iunie 2007 10:36:25
Problema P-sir Scor 0
Compilator cpp Status done
Runda preONI 2007, Runda Finala, Clasele 11-12 Marime 1.61 kb
#include <cstdio>
#include <algorithm>

using namespace std;

const int NMAX = 2008;

int N, C;
int A[NMAX], T[NMAX];
unsigned AIB[NMAX][NMAX], rez;

void read() {
	FILE *fin = fopen("psir.in", "rt");
	int i;

	fscanf(fin, " %d", &N);

	for (i = 0; i < N; ++i)
		fscanf(fin, " %d", A + i),
		T[i] = i;

	fclose(fin);
}

struct comp {
	bool operator() (const int &a, const int &b) {
		return A[a] < A[b];
	}
};

int lbit(const int &x) { return x & ~(x - 1); }

void update(int p1, int p2, unsigned val) {
	int p3;

	for (; p1 <= C; p1 += lbit(p1))
		for (p3 = p2; p3 <= C; p3 += lbit(p3))
			AIB[p1][p3] += val;
}

unsigned query(int p1, int p2) {
	unsigned rez = 0;
	int p3;

	for (; p1; p1 -= lbit(p1))
		for (p3 = p2; p3; p3 -= lbit(p3))
			rez += AIB[p1][p3];
	
	return rez;
}

void solve(void) {
	int i, j, u, v;
	unsigned r;

	sort(T, T + N, comp());

	C = 1;
	for (i = 0; i + 1 < N; ++i)
		if (A[T[i]] != A[T[i + i]])
			A[T[i]] = C++;
		else
			A[T[i]] = C;

	A[T[N - 1]] = C;
/*
	for (i = 0; i < N; ++i)
		printf("%d ", A[i]);
	printf("\n");

	for (i = 0; i < N; ++i)
		printf("%d ", T[i]);
	printf("\n");
*/
	for (i = 0; i < N; ++i)
		update(A[i], A[i], 1);
	
	for (i = 1; i < N; ++i)
		for (j = 0; i + j < N; ++j) {
			u = A[T[j]]; v = A[T[i + j]];

			if (u == v) {
				++rez;
				continue;
			}

			r = query(v - 1, v - 1) - query(u, v - 1) - 
				query(v - 1, u) + query(u, u) + 1;

			rez += r;

//			printf("%d %d %u\n", u, v, r);

			update(u, v, r);
		}
}

void write(void) {
	FILE *fout = fopen("psir.out", "wt");

	fprintf(fout, "%u\n", rez);

	fclose(fout);
}

int main(void) {

	read();

	solve();

	write();

	return 0;
}