Cod sursa(job #1083373)

Utilizator dariusdariusMarian Darius dariusdarius Data 15 ianuarie 2014 22:40:48
Problema Indep Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.66 kb
#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;
const int MAX_N = 505;
const int MAX_V = 1005;
vector< pair<int, bool> > v;
int a[MAX_N];

int cannonic_writing(int n) {
    int count = 0;
    for(int i = 2; i <= n; ++ i) {
        if(n % i == 0) {
            n /= i;
            if(n % i == 0) {
                return -1;
            }
            ++ count;
        }
    }
    return count;
}

void pregen(int max_val) {
    for(int i = 1; i <= max_val; ++ i) {
        int cannon = cannonic_writing(i);
        if(cannon != -1) {
            v.push_back(make_pair(i, static_cast<bool>(cannon % 2 == 0)));
        }
    }
}

class HugeNumber {
    public:
        HugeNumber() {
            memset(v, 0, sizeof v);
            v[0] = 1;
        }
        HugeNumber(int k) {
            memset(v, 0, sizeof v);
            do {
                v[++ v[0]] = k % 10;
                k /= 10;
            } while(k);
        }
        inline HugeNumber operator*(const HugeNumber &other) const {
            HugeNumber answer;
            answer.v[0] = v[0] + other.v[0] - 1;
            for(int i = 1; i <= v[0]; ++ i) {
                for(int j = 1; j <= other.v[0]; ++ j) {
                    answer.v[i + j - 1] += v[i] * other.v[j];
                }
            }
            int t = 0;
            for(int i = 1; i <= answer.v[0]; ++ i) {
                answer.v[i] += t;
                t = answer.v[i] / 10;
                answer.v[i] %= 10;
            }
            if(t) {
                answer.v[++ answer.v[0]] = t;
            }
            return answer;
        }
        inline void operator+=(const HugeNumber &other) {
            v[0] = max(v[0], other.v[0]);
            int t = 0;
            for(int i = 1; i <= v[0]; ++ i) {
                v[i] = v[i] + other.v[i] + t;
                t = v[i] / 10;
                v[i] %= 10;
            }
            if(t) {
                v[++ v[0]] = t;
            }
        }
        inline void operator-=(const HugeNumber &other) {
            int t = 0;
            for(int i = 1; i <= v[0]; ++ i) {
                v[i] -= (other.v[i] + t);
                if(v[i] < 0) {
                    t = 1;
                    v[i] += 10;
                } else {
                    t = 0;
                }
            }
            while(!v[v[0]]) {
                -- v[0];
            }
        }
        inline void print(ostream &fout) {
            for(int i = v[0]; i >= 1; -- i) {
                fout << v[i];
            }
            fout << endl;
        }
    private: int v[1005];
} ONE(1);
HugeNumber pow2(int n) {
    HugeNumber a(2), ans(1);
    for( ; n; n >>= 1) {
        if(n & 1) {
            ans = ans * a;
        }
        a = a * a;
    }
    return ans;
}
inline bool by_second(const pair<int, bool> &a, const pair<int, bool> &b) {
    return static_cast<int>(a.second) > static_cast<int>(b.second);
}
int main() {
    ifstream fin("indep.in");
    ofstream fout("indep.out");
    int n, max_val = -1;
    fin >> n;
    for(int i = 1; i <= n; ++ i) {
        fin >> a[i];
        max_val = max(max_val, a[i]);
    }
    pregen(max_val);
    HugeNumber answer;
    sort(v.begin(), v.end(), by_second);
    for(vector< pair<int, bool> > :: iterator it = v.begin(); it != v.end(); ++ it) {
        //fout << it->first << " " << it->second << "\n";
        int count = 0;
        for(int i = 1; i <= n; ++ i) {
            if(a[i] % it->first == 0) {
                ++ count;
            }
        }
        if(it->second) {
            answer += pow2(count);
            answer -= ONE;
        } else {
            answer -= pow2(count);
            answer += ONE;
        }
    }
    answer.print(fout);
    return 0;
}