Cod sursa(job #107)

Utilizator dominoMircea Pasoi domino Data 5 decembrie 2006 05:27:22
Problema Pedefe Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <stdio.h>
#include <string.h>

#define MAX_N 505
#define MAX_P 105
#define MAX_C 505
#define MOD 666013
#define FIN "pedefe.in"
#define FOUT "pedefe.out"
#define FOR(i, a, b) for (i = (a); i < (b); i++)
#define ADD(x, y) (((x) += (y)) >= MOD ? (x) -= MOD : 0)
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define CLEAR(x) memset(x, 0, sizeof(x))
#define LSB(x) (((x) & ((x)-1)) ^ (x))

int N, M, P, Res, A[2][MAX_N][MAX_N], bst[2][MAX_N], T[2][MAX_C], cnt[MAX_C];
int S1[MAX_N], S2[MAX_N], S3[MAX_P], Sigma;

inline void update(int *T, int n, int x)
{
    for (; n <= Sigma; n += LSB(n))
        ADD(T[n], x);
}

inline int query(int *T, int n)
{
    int t = 0;

    for (; n > 0; n -= LSB(n))
        ADD(t, T[n]); 
    return t;
}

int main(void)
{
    int i, j, k, p, crt, prev;

    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);

    scanf("%d %d %d", &N, &M, &P);
    FOR (i, 1, N+1) scanf("%d", S1+i);
    FOR (i, 1, M+1) scanf("%d", S2+i);
    FOR (i, 1, P+1) scanf("%d", S3+i);
    S1[0] = -1; S3[0] = -2;

    FOR (i, 1, N+1) cnt[S1[i]] = 1;
    FOR (i, 1, M+1) cnt[S2[i]] = 1;
    FOR (i, 1, P+1) cnt[S3[i]] = 1;
    FOR (i, 1, MAX_C) cnt[i] += cnt[i-1];
    FOR (i, 1, N+1) { S1[i] = cnt[S1[i]]; Sigma = MAX(Sigma, S1[i]); }
    FOR (i, 1, M+1) { S2[i] = cnt[S2[i]]; Sigma = MAX(Sigma, S2[i]); }
    FOR (i, 1, P+1) { S3[i] = cnt[S3[i]]; Sigma = MAX(Sigma, S3[i]); }
    Sigma++;

    A[0][0][0] = 1;
    update(T[0], S2[0]+1, 1);
    FOR (k, 0, P+1) 
    {
        crt = k&1;
        CLEAR(bst[!crt]);
        FOR (i, 0, N+1)
        {
            CLEAR(T[!crt]); CLEAR(T[crt]);            
            FOR (j, 0, M+1)
            {
                if (S1[i] == S2[j])
                {
                   prev = (S1[i] == S3[k])^crt;
                   p  = query(T[prev], S2[j]+1);
                   ADD(A[crt][i][j], p);
                }
                update(T[!crt], S2[j]+1, bst[!crt][j]);
                ADD(bst[!crt][j], A[!crt][i][j]);
                update(T[crt], S2[j]+1, bst[crt][j]);
                ADD(bst[crt][j], A[crt][i][j]);
            }
        }
        CLEAR(A[!crt]); CLEAR(bst[!crt]);
    }

    FOR (i, 1, N+1) FOR (j, 1, M+1)
        ADD(Res, A[P&1][i][j]);
    printf("%d\n", Res);

    return 0;
}