Cod sursa(job #1049728)

Utilizator Mihai22eMihai Ionut Enache Mihai22e Data 7 decembrie 2013 19:00:46
Problema Indep Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.88 kb
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

const int MAX_N = 502;
const int MAX_VAL = 1001;
const int MAX_D = 155;

typedef int Huge[MAX_D];

int N;
int v[MAX_N], gcd[MAX_VAL][MAX_VAL];
Huge dp[2][MAX_VAL];

void read() {
    freopen("indep.in", "r", stdin);

    scanf("%d", &N);
    for(int i = 1; i <= N; ++i)
        scanf("%d", &v[i]);
}

inline int get_gcd(int a, int b) {
    int r;

    while(b) {
        r = a % b;
        a = b;
        b = r;
    }

    return a;
}

void add(Huge a, Huge b) {
    int t = 0;

    if(b[0] > a[0])
        a[0] = b[0];
    for(int i = 1; i <= a[0]; ++i) {
        a[i] += b[i] + t;
        t = a[i] / 10000000;
        a[i] %= 10000000;
    }
    while(t)
        a[++a[0]] = t % 10, t /= 10;
}

void preprocess() {
    for(int i = 1; i < MAX_VAL; ++i)
        for(int j = i; j < MAX_VAL; ++j) {
            gcd[i][j] = get_gcd(i, j);
            gcd[j][i] = gcd[i][j];
        }
}

void Huge_copy(Huge a, Huge b) {
    for(int i = 1; i <= a[0]; ++i)
        a[i] = 0;
    for(int i = 0; i <= b[0]; ++i)
        a[i] = b[i];
}

void solve() {
    Huge one;
    for(int i = 0; i < MAX_D; ++i)
        one[i] = 0;
    one[0] = one[1] = 1;

    preprocess();
    Huge_copy(dp[1][v[1]], one);
    for(int i = 2; i <= N; ++i) {
        int r = i % 2;
        for(int j = 1; j < MAX_VAL; ++j)
            Huge_copy(dp[r][j], dp[r ^ 1][j]);
        for(int j = 1; j < MAX_VAL; ++j)
            add(dp[r][gcd[v[i]][j]], dp[r ^ 1][j]);
        add(dp[r][v[i]], one);
    }
}

void write() {
    freopen("indep.out", "w", stdout);

    printf("%d", dp[N % 2][1][dp[N % 2][1][0]]);
    for(int i = dp[N % 2][1][0] - 1; i >= 1; --i)
        printf("%07d", dp[N % 2][1][i]);
    printf("\n");
}

int main() {
    read();
    solve();
    write();

    return 0;
}