Cod sursa(job #67874)

Utilizator vmaneavmanea vmanea Data 25 iunie 2007 19:36:26
Problema P-sir Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define nmax 2002

#define MOD 4294967295L

int V[nmax], X[nmax], Y[nmax], P[nmax], NRI[nmax], NRC[nmax], NRU[nmax];

/*int *NRmu[nmax], *UNUm[nmax];

int *NRMC[nmax], *UNUM[nmax];*/

int NRmu[nmax][nmax], UNUm[nmax][nmax];

int NRMC[nmax][nmax], UNUM[nmax][nmax];

int N, i, j, k, vmin, vmax;


void msort(int l, int r)
{
	if (l >= r)
		return;

	int m = (l+r) >> 1;

	msort(l, m);

	msort(m+1, r);

	for (i = k = l, j = m+1; i <= m && j <= r;)
		if (V[i] < V[j])
		{
			X[k] = V[i];
			Y[k++] = P[i++];
		}
		else
		{
			X[k] = V[j];
			Y[k++] = P[j++];
		}

	while (i <= m)
	{
		X[k] = V[i];
		Y[k++] = P[i++];
	}

	while (j <= r)
	{
		X[k] = V[j];
		Y[k++] = P[j++];
	}

	for (i = l; i <= r; i++)
	{
		V[i] = X[i];
		P[i] = Y[i];
	}
}


int main(void)
{

	freopen("psir.in", "r", stdin);

	freopen("psir.out", "w", stdout);

	scanf("%d", &N);


	for (i = 1; i <= N; i++)
	{
		P[i] = i;

		scanf("%d", &V[i]);
	}

	msort(1, N);

	// trebuie sa le aduc la forma initiala!!!

	for (i = 0, j = 1; j <= N; j++)
	{
		if (V[j] > V[j-1]) i++;

		V[j] = i;
	}

	vmax = i;

	for (i = vmin = 1; i <= N; i++)
		X[P[i]] = V[i];

	for (i = 1; i <= N; i++)
		V[i] = X[i];


	/*

	for (i = 1; i <= N; i++)
	{
		NRmu[i] = (int *)realloc(NRmu[i], (vmin + vmax) * sizeof(int));
		NRMC[i] = (int *)realloc(NRMC[i], (vmin + vmax) * sizeof(int));

		UNUM[i] = (int *)realloc(UNUM[i], (vmin + vmax) * sizeof(int));
		UNUm[i] = (int *)realloc(UNUm[i], (vmin + vmax) * sizeof(int));

		for (j = vmin; j <= vmax; j++)
			NRmu[i][j] = NRMC[i][j] = UNUm[i][j] = UNUM[i][j] = 0;
	}

	*/

	for (i = 1; i <= N; i++)
	{
		for (j = V[i]+1; j <= vmax; j++)
		 UNUm[i][j] = 1 + (UNUm[i-1][j] % MOD) % MOD;

		for (j = V[i]-1; j >= vmin; j--)
		 UNUM[i][j] = 1 + (UNUM[i-1][j] % MOD) % MOD;
	}

	for (i = 2; i <= N; i++)
	{
		NRU[i] = NRC[i] = 0;

		for (j = 2; j < i; j++)
		  if (P[j] > P[i])
		  {
		    // urca de la i la j
		    NRU[i] = ((NRU[i] % MOD + NRmu[j-1][P[i]] % MOD) % MOD + UNUm[j-1][P[i]] % MOD) % MOD;
		  }
		  else
		  {
		    // coboara de la i la j
		    NRC[i] = ((NRC[i] % MOD + NRMC[j-1][P[i]] % MOD) % MOD + UNUM[j-1][P[i]] % MOD) % MOD;
		  }

		NRI[i] = ((NRU[i] % MOD + NRC[i] % MOD ) % MOD + (i-1) % MOD) % MOD;

		for (j = V[i]+1; j <= vmax; j++)
		{
		  NRmu[i][j] = (NRU[i] % MOD + NRmu[i-1][j] % MOD) % MOD;
		}

		for (j = V[i]-1; j >= vmin; j--)
		{
		  NRMC[i][j] = (NRC[i] % MOD + NRMC[i-1][j] % MOD) % MOD;
		}
	}

	for (i = 1; i <= N; i++)
	{
	  NRI[0] = (NRI[0] % MOD + NRI[i] % MOD) % MOD;
	}

	printf("%d\n", NRI[0]);

	return 0;
}