Cod sursa(job #935408)

Utilizator manciu_ionIon Manciu manciu_ion Data 3 aprilie 2013 13:33:32
Problema Pedefe Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.17 kb

#include <cstdio>
#include <cstring>

using namespace std;

const int maxN = 504;
const int maxP = 104;
const int mod = 666013;
const int sigma = 500;

int N, M, P;
int A[maxN], B[maxN], C[maxP];
int D0[maxN][maxN], D1[maxN][maxN];
int aib[maxN][maxN];

inline int lsb(int x) {
    return ((x & (x - 1)) ^ x);
}

inline void update(int which, int poz, int val) {
    int i;
    for (i = poz; i <= sigma; i += lsb(i)) {
        aib[which][i] += val;
        if (aib[which][i] >= mod)
            aib[which][i] -= mod;
    }
}

inline int query(int which, int poz) {
    int i, rez = 0;
    for (i = poz; i > 0; i -= lsb(i)) {
        rez = rez + aib[which][i];
        if (rez >= mod)
            rez -= mod;
    }

    return rez;
}

int main() {
    int i, j, k;
    freopen("pedefe.in", "r", stdin);
    freopen("pedefe.out", "w", stdout);

    scanf("%d%d%d", &N, &M, &P);
    for (i = 1; i <= N; i++)
        scanf("%d", &A[i]);
    for (i = 1; i <= M; i++)
        scanf("%d", &B[i]);
    for (i = 1; i <= P; i++)
        scanf("%d", &C[i]);

    D1[0][0] = 1;
    A[0] = B[0] = 1;

    for (i = 0; i <= P; i++) {

        memmove(D0, D1, sizeof(D1));
        memset(D1, 0, sizeof(D1));
        memset(aib, 0, sizeof(aib));

        for (j = 0; j <= N; j++) {
            int suma = 0;
            for (k = 0; k <= M; k++) {
                suma = suma + D0[j][k];
                if (suma >= mod)
                    suma -= mod;
                if (suma)
                    update(k, A[j], suma);

                if (j < N && k < M && A[j + 1] == B[k + 1]) {
                    if (A[j + 1] == C[i + 1]) {
                        D1[j + 1][k + 1] += query(k, A[j + 1]);
                        if (D1[j + 1][k + 1] >= mod)
                            D1[j + 1][k + 1] -= mod;
                    }
                    else {
                        D0[j + 1][k + 1] += query(k, A[j + 1]);
                        if (D0[j + 1][k + 1] >= mod)
                            D0[j + 1][k + 1] -= mod;
                    }
                }
            }
        }
    }


    printf("%d\n", query(M, sigma));

    return 0;
}