Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- using LL = long long;
- #define V vector
- #define FOR(i, l, r) for(int i = (l); i <= (r); ++i)
- #define REP(i, n) FOR(i, 0, (n) - 1)
- template<class T> int size(T &&x) {
- return int(x.size());
- }
- template<class A, class B> ostream& operator<<(ostream &out, const pair<A, B> &p) {
- return out << '(' << p.first << ", " << p.second << ')';
- }
- template<class T> auto operator<<(ostream &out, T &&x) -> decltype(x.begin(), out) {
- out << '{';
- for(auto it = x.begin(); it != x.end(); ++it)
- out << *it << (it == prev(x.end()) ? "" : ", ");
- return out << '}';
- }
- void dump() {}
- template<class T, class... Args> void dump(T &&x, Args... args) {
- cerr << x << "; ";
- dump(args...);
- }
- #ifdef DEBUG
- struct Nl{~Nl(){cerr << '\n';}};
- # define debug(x...) cerr << (strcmp(#x, "") ? #x ": " : ""), dump(x), Nl(), cerr << ""
- #else
- # define debug(x...) 0 && cerr
- #endif
- mt19937_64 rng(0);
- int rd(int l, int r) {
- return uniform_int_distribution<int>(l, r)(rng);
- }
- constexpr LL Mod = 1e9+7;
- LL mul(LL a, LL b, LL mod) {
- return (a * b - LL((long double) a * b / mod) * mod + mod) % mod;
- }
- LL fpow(LL a, LL n, LL mod) {
- if(n == 0)
- return 1;
- if(n % 2 == 1)
- return mul(fpow(a, n - 1, mod), a, mod);
- LL ret = fpow(a, n / 2, mod);
- return mul(ret, ret, mod);
- }
- bool miller_rabin(LL n) {
- if(n < 2)
- return false;
- int r = 0;
- LL d = n - 1;
- while(d % 2 == 0)
- d /= 2, r++;
- for(int a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31}) {
- if(n == a)
- return true;
- LL x = fpow(a, d, n);
- if(x == 1 or x == n - 1)
- continue;
- bool composite = true;
- REP(i, r - 1) {
- x = mul(x, x, n);
- if(x == n - 1) {
- composite = false;
- break;
- }
- }
- if(composite)
- return false;
- }
- return true;
- }
- LL dzielnikow(LL n) {
- LL cp_n = n;
- LL wynik = 1;
- FOR(i, 2, n) {
- if(i * LL(i) * LL(i) > n)
- break;
- int cnt = 0;
- while(cp_n % i == 0) {
- ++cnt;
- cp_n /= i;
- }
- wynik *= (cnt + 1);
- }
- n = cp_n;
- auto dokoncz = [&] {
- if(n == 1)
- return 1;
- if(miller_rabin(n))
- return 2;
- int sq = int(sqrt(n));
- FOR(i, sq - 2, sq + 2)
- if(i * LL(i) == n)
- return 3;
- return 4;
- };
- return wynik * dokoncz();
- }
- LL roz(LL x, LL y) {
- return ((x - y >= 0) ? (x - y) : (x - y + Mod));
- }
- int main() {
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- int n; cin >> n;
- V<LL> v(n);
- REP(i, n)
- cin >> v[i];
- V<int> div(n);
- REP(i, n)
- div[i] = dzielnikow(v[i]);
- LL start = 1;
- REP(i, n) {
- start *= div[i];
- start %= Mod;
- }
- for(int mask = 1; mask < (1 << n); mask++) {
- int bits = __builtin_popcount(mask);
- if(bits > 1) {
- debug(mask);
- // dodawanko
- LL g = 0; // gcd
- REP(i, n)
- if(mask & (1 << i))
- g = __gcd(g, v[i]);
- debug(g);
- LL how_many = dzielnikow(g);
- REP(i, n)
- if(~mask & (1 << i))
- how_many = (how_many * div[i]) % Mod;
- debug(how_many);
- how_many = (how_many * (bits - 1)) % Mod;
- start = ((bits & 1) ? (start + how_many) % Mod : roz(start, how_many));
- }
- }
- cout << start << '\n';
- return 0;
- }
- 4
- 2 1 7 2
- mask: 3;
- g: 1;
- how_many: 4;
- mask: 5;
- g: 1;
- how_many: 2;
- mask: 6;
- g: 1;
- how_many: 4;
- mask: 7;
- g: 1;
- how_many: 2;
- mask: 9;
- g: 2;
- how_many: 4;
- mask: 10;
- g: 1;
- how_many: 4;
- mask: 11;
- g: 1;
- how_many: 2;
- mask: 12;
- g: 1;
- how_many: 2;
- mask: 13;
- g: 1;
- how_many: 1;
- mask: 14;
- g: 1;
- how_many: 2;
- mask: 15;
- g: 1;
- how_many: 1;
- 1000000006
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement