Cod sursa(job #93137)

Utilizator fireatmyselfBogdan-Alexandru Stoica fireatmyself Data 17 octombrie 2007 20:21:15
Problema P-sir Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 2.9 kb
#include <stdio.h>

#define MOD 2147483647
#define NMAX 2002
#define TMAX 2048

unsigned int A[2][NMAX], Nr, Total, T[2*TMAX];
int N, X, Y, V[NMAX], v[NMAX], p[NMAX];

unsigned int B[2][NMAX], S[NMAX], Brut;

void readandnormalize()
{
        int i, j, aux;
        freopen("psir.in", "r", stdin);
        scanf("%d", &N);
        for (i = 0; i < N; i++) scanf("%d", v+i), p[i] = i;

        for (i = 0; i < N; i++)
            for (j = i+1; j < N; j++)
                if (v[i]>v[j])
                {
                   aux = v[i]; v[i] = v[j]; v[j] = aux;
                   aux = p[i]; p[i] = p[j]; p[j] = aux;
                }

        for (i = 0, aux = 1; i < N; i++) {
            V[ p[i] ] = aux;
            if (v[i]!=v[i+1]) aux++;
             }
}

void update(int x, int v)
{
        int n = TMAX+x;

        T[n] += v;

        while (n>1)
        {
                n = n>>1;
                T[n] += v;
        }
}

void query(int p, int q, int n)
{
        int md = (p+q)>>1, l = n<<1;

        if (X <= p && q <= Y)
        {
                Nr += T[n];
                return;
        }

        if (p>q) return;

        if ( (p <= X && X <= q) || (p <= Y && Y <= q) )
        {
                query(p, md, l);
                query(md+1, q, l+1);
        }
}

void solve()
{
        int s = 0, d = 1;
        int i, j;

        for (i = 1; i < N; i++)
        {
            memset(T,0,sizeof(T));
            for (j = 0; j < i; j++)
            {
                update(V[j], A[s][j]);
                if (V[i]!=V[j])
                {
                        Nr = 0;
                        if (V[i]>V[j]) X = V[i]+1, Y = N+1;
                        else X = 0, Y = V[i]-1;
                        query(0, TMAX-1, 1);
                        A[d][j] = (A[d][j]+Nr)&MOD;
                }
                A[d][j] = (A[d][j]+1)&MOD;
                Total = (Total+A[d][j])&MOD;
            }
            s = (s+1)&1; d = (d+1)&1;
            for (j = 0; j < N; j++) A[d][j] = 0;
        }
}

void brut()
{
        int i, j, k, s = 0, d = 1;

        S[0] = 1;
        for (i = 1; i < N; i++)
        {
            for (j = 0; j < i; j++)
            {
                B[d][j]++;
                for (k = 0; k < j; k++)
                    if ( ((V[i]-V[j])*(V[i]-V[k]))<0 )
                       B[d][i] = (S[k]+B[d][i])&MOD;
            }
            for (j = 0; j < N; j++) S[i] = (S[i]+B[d][j])&MOD;
            Brut = (Brut+S[i])&MOD;
            s = (s+1)&1; d = (d+1)&1;
            for (j = 0; j < N; j++) B[d][j] = 0;
        }
}

void write()
{
        freopen("psir.out", "w", stdout);
        printf("%d\n", Total);
//        freopen("brut.out", "w", stdout);
//        printf("%d\n", Brut);
}

int main()
{
        readandnormalize();
        solve();
//        brut();
        write();
        return 0;
}