Cod sursa(job #67622)

Utilizator MariusMarius Stroe Marius Data 25 iunie 2007 12:47:05
Problema P-sir Scor 30
Compilator cpp Status done
Runda preONI 2007, Runda Finala, Clasele 11-12 Marime 2.28 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

const char iname[] = "psir.in";
const char oname[] = "psir.out";

#define MAX_N  2000

typedef unsigned int i32;

typedef long long i64;

const i64 modulo = 0xffffffff;
//const i64 modulo = 4294967295LL;

int n, P[MAX_N], m, Q[MAX_N], log;


void read_in(void)
{    
     FILE *fi = fopen(iname, "r");
     int i;
     
     fscanf(fi, "%d", &n);
     for (i = 0; i < n; ++ i)
         fscanf(fi, "%d", &P[i]), Q[i] = P[i];
     fclose(fi);
     
     sort(Q, Q + n);
     for (i = m = 0; i < n; ++ i) {
         if (i == 0)
             m ++;
         else if (i > 0) 
             if (Q[m - 1] != Q[i]) 
                 Q[m ++] = Q[i];
     }
     for (log = 1; log < m; log <<= 1) ;
}

i32 A[MAX_N][MAX_N];

int search(int Q[], int n, int val)
{
    int k;
    int stp = log;

    for (k = 0; stp; stp >>= 1) {
        if ((k + stp < n) && (Q[k + stp] <= val))
            k = k + stp;
    }
    return k;
}

i64 query(i32 A[], int lo, int hi)
{
    i64 sum;
 
    if (lo > 0)   
        sum = ((i64)A[hi]) - ((i64)A[lo - 1]);
    else
        sum = ((i64)A[hi]);
    if (sum < 0)
        sum += modulo;
    return sum;
}

i32 f(void)
{
    int i;
    int j;
    int k;
    i64 cnt;
    i64 rez = 0;
    i64 tmp;
    
    for (i = 1; i < n; ++ i) {
        for (j = 0; j < i; ++ j) {
            cnt = 0;
            k = search(Q, m, P[i]);
            if (P[j] < P[i])   // aduna elementele mai mari decat P[i]
                cnt = query(A[j], k + 1, m - 1);
            else if (P[j] > P[i])   // aduna elementele mai mici decat P[i]
                cnt = query(A[j], 0, k - 1);
            
            k = search(Q, m, P[j]);
            tmp = (((i64)A[i][k]) + (cnt + 1)) & modulo;
            A[i][k] = ((i32)tmp);     // update
            
            rez = (rez + (cnt + 1)) & modulo; 
        }
        for (j = 1; j < m; ++ j) {
            tmp = (((i64)A[i][j]) + ((i64)A[i][j - 1])) & modulo;
            A[i][j] = ((i32)tmp);
        }
    }
    return (i32)rez;
}

void print(const i32 ans)
{
     FILE *fo = fopen(oname, "w");
     fprintf(fo, "%u\n", ans);
     fclose(fo);
}

int main(void)
{
    read_in();
    print(f());
    return 0;
}