Cod sursa(job #843166)

Utilizator stoicatheoFlirk Navok stoicatheo Data 27 decembrie 2012 15:21:32
Problema Pedefe Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 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++) {  
 
        memcpy(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;
}