Cod sursa(job #1000337)

Utilizator romircea2010FMI Trifan Mircea Mihai romircea2010 Data 22 septembrie 2013 18:22:04
Problema Indep Scor 85
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.74 kb
#include <fstream>
#include <cstdio>
#define NMax 510
#define ValMax 1010

using namespace std;

int n, a[NMax], maxim;
int dp[2][ValMax][1024];
int mat[ValMax][ValMax];

inline int max(int x, int y)
{
    return x>y?x:y;
}

inline void Read()
{
    freopen ("indep.in", "r", stdin);
    scanf("%d", &n);
    int i;
    for (i=1; i<=n; ++i)
    {
        scanf ("%d", &a[i]);
        maxim = max(maxim, a[i]);
    }
}
inline void Adunare(int *A, int *B)
{
    int i, t = 0;
    for (i=1; i<=A[0] || i<=B[0] || t; ++i, t/=1000000000)
        A[i] = (t += A[i] + B[i]) % 1000000000;
    A[0] = i - 1;
}

inline int cmmdc(int x, int y)
{
    int r;
    while (y)
    {
        r = x%y;
        x = y;
        y = r;
    }
    return x;
}


inline void Solve()
{
    /// dp[i][j] = numarul de subsiruri existente folosind elemente din primele i cu cmmdc = j
    /// dp[i][j] -> dp[i+1][j]

    int i, p, q, j, k;
    for (i=1; i<=n; ++i)
        for (j=1; j<=maxim; ++j)
            mat[a[i]][j] = mat[j][a[i]] = cmmdc(a[i], j);
    int unu[2];
    unu[0] = unu[1] = 1;
    for (i=1, p=1, q=0; i<=n; ++i, swap(p, q))
    {
        Adunare(dp[p][a[i]], unu);
        for (j=1; j<=maxim; ++j)
        {
            Adunare(dp[p][j], dp[q][j]);
            Adunare(dp[p][mat[j][a[i]]], dp[q][j]);
            for (k = dp[q][j][0]; k>=0; --k)
                dp[q][j][k] = 0;
        }
    }
    freopen ("indep.out", "w", stdout);
    if (dp[q][1][0] == 0)
    {
        printf("0\n");
        return ;
    }
    printf ("%d", dp[q][1][dp[q][1][0]]);
    for (i=dp[q][1][0] - 1; i; --i)
        printf ("%09d", dp[q][1][i]);
    printf("\n");
}

int main()
{
    Read();
    Solve();
    return 0;
}