# ZeroJudge - c627: 階乘問題
### 題目連結:https://zerojudge.tw/ShowProblem?problemid=c627
###### tags: `ZeroJudge` `數學` `數論` `字串`
```cpp=
#include <iostream>
#include <string>
using namespace std;
#define MOD 1000000007
#define HALF 500000003
#define SEGMENT 100
#define SEGMENT_SIZE 5000001
int factorials[SEGMENT] = { 1, 179975082, 844717325, 162073520, 975907481, 560671497, 728224171, 710049900, 487675066, 950116878, 338114821, 5594049, 220353266, 111685388, 660041081, 486487453, 238533824, 183683222, 181714903, 4584842, 513016973, 563225563, 664207631, 359404206, 405210013, 891104157, 204049728, 337692890, 592577093, 378800810, 843425276, 772173014, 33521380, 487435535, 475662066, 826408248, 303162816, 496947126, 607013085, 703602602, 113047135, 361370286, 926799997, 659454588, 125621224, 730253449, 472223268, 397456269, 916388158, 771170692, 901704713, 510768, 421156782, 207568233, 463419638, 339347587, 878794298, 715710121, 600548870, 329625190, 957550814, 3116882, 901086579, 58300397, 523691175, 622208068, 670043286, 719862532, 143252882, 777461135, 303963716, 523828672, 121564163, 280416267, 972474354, 214646942, 756530398, 873446650, 86728354, 786588856, 162507066, 96186670, 840094625, 84081882, 825801755, 904106065, 180609570, 504297657, 285785677, 658176309, 601129725, 894835412, 935791236, 175685608, 54650636, 392701728, 883525257, 406902789, 620029448, 572348605 };
static const auto Initialize = [] {
cin.sync_with_stdio(false); cin.tie(nullptr);
/*int buffer = 1, pointer = 1;
for (int i = 1, j = 1; i <= HALF; ++i, ++j) {
buffer = ((long long)buffer * i) % MOD;
if (j == SEGMENT_SIZE) {
factorials[pointer] = buffer;
cout << ", " << factorials[pointer];
++pointer; j = 0;
}
}*/
return nullptr;
}();
int ModularInverse(int number) {
int answer = 1, base = number, power = MOD - 2;
while (power) {
if (power & 1)
answer = ((long long)answer * base) % MOD;
base = ((long long)base * base) % MOD;
power >>= 1;
}
return answer;
}
int CompactFactorial(int number) {
int position = (number / SEGMENT_SIZE) * SEGMENT_SIZE, answer = factorials[number / SEGMENT_SIZE];
while (position < number) {
++position;
answer = ((long long)answer * position) % MOD;
}
return answer;
}
int Factorial(int number) {
static int wilson = MOD - 1;
if (number <= HALF)
return CompactFactorial(number);
number = MOD - number - 1;
return ((long long)wilson * ModularInverse(number & 1 ? MOD - CompactFactorial(number) : CompactFactorial(number))) % MOD;
}
int main() {
string number;
while (cin >> number)
if (number.size() > 10 || (number.size() == 10 && number >= "1000000007"))
cout << "0\n";
else
cout << Factorial(stoi(number)) << '\n';
}
```