# 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'; } ```