Cod sursa(job #93372)

Utilizator fireatmyselfBogdan-Alexandru Stoica fireatmyself Data 18 octombrie 2007 17:19:47
Problema P-sir Scor 30
Compilator c Status done
Runda Arhiva de probleme Marime 2.8 kb
#include <stdio.h>
#include <string.h>

#define NMAX 2002
#define TMAX 2048

unsigned int A[NMAX][NMAX], Nr, Total, T[2*TMAX], MOD = (1<<30);
int N, X, Y, V[NMAX], v[NMAX], p[NMAX];

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

void readandnormalize()
{
        int i, j, aux;
        MOD = 4*MOD-1;
        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 i, j;

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

        for (i = 0; i < N; i++)
            for (j = 0; j < N; j++) Total += A[i][j];
        i = 0;
}

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

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

        for (i = 0; i < N; i++)
            for (j = 0; j < N; j++) Brut += B[i][j];
        i = 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;
}