Cod sursa(job #1585790)

Utilizator claudiuarseneClaudiu Arsene claudiuarsene Data 31 ianuarie 2016 14:42:50
Problema Indep Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.85 kb
#include <fstream>
#include <iostream>
#include <array>
#include <algorithm>
using namespace std;

class bignum{
    array<long long, 150> buf;
public:
    static constexpr long long baza = 1000000000000000000;
    bignum(): buf({}){}
    void operator=(const bignum& rhs){
        buf = rhs.buf; }
    void operator++(){
        long long x = 1;
        for(int i = 0; i < 150; ++i){
            x += buf[i];
            buf[i] = x%baza;
            x /= baza; } }
    void operator+=(const bignum& rhs){
        long long x = 0;
        for(int i = 0; i < 150; ++i){
            x += buf[i];
            x += rhs.buf[i];
            buf[i] = x%baza;
            x /= baza; } }
    friend ofstream& operator<<(ofstream& lhs, const bignum& rhs); };

ofstream& operator<<(ofstream& lhs, const bignum& rhs){
    string str;
    for(int i = 0; i < 150; ++i){
        for(int x = rhs.buf[i], j = 0; j < 18; x /= 10, ++j){
            str.push_back(x%10 + '0'); } }
    while(str.back() == '0'){
        str.pop_back(); }
    reverse(begin(str), end(str));
    lhs << str;
    return lhs; }

constexpr int gcd(const int a, const int b){
    return b == 0 ? a : gcd(b, a%b); }

int main(){
    ifstream f("indep.in");
    ofstream g("indep.out");
    array<array<int, 1001>, 1001> gcd_table;

    for(int i = 0; i <= 1000; ++i){
        gcd_table[i][0] = gcd_table[0][i] = i; }
    for(int i = 1; i <= 1000; ++i){
        for(int j = 1; j <= i; ++j){
            gcd_table[i][j] = gcd_table[j][i] = gcd_table[i-j][j]; } }

    int n;
    f >> n;
    array<array<bignum, 1001>, 2> d = {};

    for(int i = 0, x; i < n; ++i){
        f >> x;
        d[i%2] = d[(i+1)%2];
        for(int j = 1; j <= 1000; ++j){
            d[i%2][gcd_table[j][x]] += d[(i+1)%2][j]; }
        ++d[i%2][x]; }
    g << d[(n+1)%2][1] << '\n';
    return 0; }