#include typedef long long ll; typedef unsigned long long ull; #define FOR(i,a,b) for(int (i)=(a);i<(int)(b);i++) #define REP(i,n) FOR(i,0,n) #define RANGE(vec) (vec).begin(),(vec).end() template T gcd(T a, T b) { if ( std::abs(a) < std::abs(b) ) std::swap(a,b); if ( b == 0 ) return a; return gcd(b, a%b); } class Fact { std::vector inv_; std::vector fact_; std::vector factr_; public: // O(maxN) Fact(int maxN, long long P) { long long ModP = P; inv_.resize(maxN+1,0); fact_.resize(maxN+1,0); factr_.resize(maxN+1,0); inv_[1] = fact_[0] = factr_[0] = 1; for (int i = 2; i <= maxN; ++i) inv_[i] = inv_[ModP % i] * (ModP - ModP/i) % ModP; for (int i = 1; i <= maxN; ++i) { fact_[i] = fact_[i-1]*i % ModP; factr_[i] = factr_[i-1]*inv_[i] % ModP; } } long long fact(long long n) { return fact_[n]; } long long factr(long long n) { return factr_[n]; } long long inv(long long n) { return inv_[n]; } }; using namespace std; const int Mod = (int)(1E+9)+7; class EvilPetal { public: void solve(void) { const int maxN = (int)1E+6; int K; cin>>K; vector C(K); int T = 0; REP(i,K) { cin>>C[i]; T += C[i]; } // C[i] 全てをならべて作った花弁は T 回転させると元に戻る // 花弁の作り方のうち k 回転させて元に戻るものを考える // すると T%k==0 になるはず。 // つまり要素 k 個をならべたグループを考えてそれが T/k の周期をもつということ。 // // [abcde][abcde]...[abcde] // <--k--> // <--------- T ----------> // // 一つのグループに C[i] の色が j 個現れるとすると、C[i] 全て使いきらないといけないので // // C[i] == (T/k) * j ... (※) // // となる。 よってグループの周期 (T/k) が取りうる値は全ての C[i] の最大公約数の約数となる。 // あとは [abcde] の取りうる組み合わせを計算すればよい。 // int g = C[0]; FOR(i,1,K) g = gcd(g, C[i]); vector gsize; // 各周期に対応するグループの長さを格納 for (int pd = 1; pd*pd <= g ; ++pd) { if ( g % pd != 0 ) continue; gsize.push_back(T/pd); if (g/pd != pd) gsize.push_back(T/(g/pd)); } // 周期が pd のグループ [abcd..] のとり得る組み合わせは // // (T/pd)!/Π(C[i]/pd)! // // となる。(※より C[i]/pd が一つのグループで使われる C[i] の色の数) // // [abcd] を考えるときに [abab] のようにグループの長さの約数に // なるようなサブグループによる繰り返し // は重複してかぞえられてしまうのでその分を引けば良い // Fact f(maxN, Mod); // 1/n, n!, 1/n! (mod P) 計算モジュール vector num(maxN+1,0); // 重複削除のためグループの長さが短いものから数える ll tot = 0; sort(RANGE(gsize)); REP(i,gsize.size()) { int gs = gsize[i]; ll cnt = f.fact(gs); REP(j,K) // period = T/gs cnt = cnt * f.factr(C[j]/(T/gs)) % Mod; // 計算済みのサブグループによる重複を削除する REP(j,i) { // 長さが約数になっているサブグループ if (gs % gsize[j] == 0) { cnt -= num[gsize[j]]; (cnt += Mod) %= Mod; } } num[gs] = cnt; // [abcd][abcd]...[abcd] // ^ // [abcd][abcd]...[abcd] // ^ // スタート位置の固定の仕方は gs 通りあるのでその分の重複を避けるため * 1/gs (tot += num[gs]*f.inv(gs)%Mod) %= Mod; } cout<solve(); delete obj; return 0; } #endif