結果
問題 | No.377 背景パターン |
ユーザー |
![]() |
提出日時 | 2016-06-08 21:38:37 |
言語 | C90 (gcc 12.3.0) |
結果 |
CE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 3,559 bytes |
コンパイル時間 | 85 ms |
コンパイル使用メモリ | 27,776 KB |
最終ジャッジ日時 | 2025-01-08 12:43:38 |
合計ジャッジ時間 | 551 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
コンパイルエラー時のメッセージ・ソースコードは、提出者また管理者しか表示できないようにしております。(リジャッジ後のコンパイルエラーは公開されます)
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
ただし、clay言語の場合は開発者のデバッグのため、公開されます。
コンパイルメッセージ
main.c:25:1: error: C++ style comments are not allowed in ISO C90 25 | // K^e (mod M)の計算 | ^ main.c:25:1: note: (this will be reported only once per input file)
ソースコード
#include <stdio.h> #include <stdlib.h> typedef long long int ll; int H,W,K; ll gcd(ll a, ll b) { int c; if (a < b) { c = a; a = b; b = c; } while (b != 0) { c = a%b; a = b; b = c; } return a; } ll lcm(ll a, ll b) { return a*b/gcd(a,b); } int M = 1000000007; // K^e (mod M)の計算 ll pow_mod_K(ll K, ll e) { if (K == 1) { return 1; } // K^(2^0), K^(2^1), ... , K^(2^n) static ll *KE = 0; int sz = 0; int i; if (KE == 0) { i = H; while (i != 0) { sz++; i>>=1; } sz++; i = W; while (i != 0) { sz++; i>>=1; } sz++; KE = (ll *)malloc(sizeof(ll)*sz); KE[0] = K%M; for (i=1; i<sz; i++) KE[i] = (KE[i-1]*KE[i-1])%M; } ll K2 = 1; i = 0; while (e != 0) { if (e&1) { K2 *= KE[i]; K2 %= M; } i++; e>>=1; } return K2; } // B^e (mod M)の計算 ll pow_mod(ll B, ll e) { if (B == 1) { return 1; } ll B2 = 1; B %= M; while (e != 0) { if (e&1) { B2 *= B; B2 %= M; } B = B*B; B %= M; e>>=1; } return B2; } // (2^3)^9 < 10^9 < (2^4)^9 ll P[4*9]; int E[4*9]; int Pend = 0; int factor(ll N) { ll p; int e; p=2; if (N%p == 0) { P[Pend] = p; e=1; for (N/=p; N%p==0; N/=p) e++; E[Pend] = e; Pend++; } for (p=3; p*p<=N; p+=2) { if (N%p == 0) { P[Pend] = p; e=1; for (N/=p; N%p==0; N/=p) e++; E[Pend] = e; Pend++; } } if (N != 1) { P[Pend] = N; E[Pend] = 1; Pend++; } return 0; } // e >= 0 // d^e ll pwr(ll d, int e) { if (d == 1) { return 1; } ll dd = 1; while (e != 0) { if (e&1) { dd *= d; } d = d*d; e>>=1; } return dd; } int cmpr(const void *a, const void *b) { if (*(ll *)a < *(ll *)b) { return -1; } else if (*(ll *)a > *(ll *)b) { return 1; } else { return 0; } } // Nの全約数生成 void initD(int N, ll **aD, int *aDsz) { Pend = 0; factor(N); int i; ll *D; int Dsz = 1; for (i=0; i<Pend; i++) Dsz *= (E[i]+1); D = (ll *)malloc(sizeof(ll)*Dsz); for (i=0; i<Dsz; i++) D[i] = 1; int j,k,l; int rpt = 1; for (i=0; i<Pend; i++) { for (j=0, k=0; j<Dsz; ) { for (l=0; l<rpt; l++) { D[j] *= pwr(P[i],k); j++; } k++; k %= (E[i]+1); } rpt *= (E[i]+1); } qsort(D, Dsz, sizeof(ll), cmpr); (*aD) = D; (*aDsz) = Dsz; } ll T_mod(ll x, int pos, ll *D, int Dsz, ll *DP) { ll T; if (DP[pos] == 0) { T = D[Dsz-1]/x; int i; for (i=pos+1; i<Dsz; i++) { if ((x<D[i]) && (D[i]%x == 0)) { T -= T_mod(D[i], i, D, Dsz, DP); T %= M; } } T += (T<0?M:0); DP[pos] = T; } else { T = DP[pos]; } return T; } int main() { scanf("%d %d %d", &H, &W, &K); ll *H_D; ll *W_D; int H_Dsz; int W_Dsz; initD(H, &H_D, &H_Dsz); initD(W, &W_D, &W_Dsz); int i; ll *H_DP; ll *W_DP; H_DP = (ll*)malloc(sizeof(ll)*H_Dsz); W_DP = (ll*)malloc(sizeof(ll)*W_Dsz); for (i=0; i<H_Dsz; i++) H_DP[i] = 0; for (i=0; i<W_Dsz; i++) W_DP[i] = 0; int j; ll e,B,h,w; ll sum = 0; h = H; w = W; for (i=0; i<H_Dsz; i++) { for (j=0; j<W_Dsz; j++) { e = (w*h)/lcm(H/H_D[i],W/W_D[j]); B = pow_mod_K(K, e); B *= T_mod(H_D[i],i,H_D,H_Dsz,H_DP); B %= M; B *= T_mod(W_D[j],j,W_D,W_Dsz,W_DP); B %= M; sum += B; sum %= M; } } // フェルマーの小定理より // (W*H)^(-1)==(W*H)^(M-2) (mod M) printf("%lld\n", (sum*pow_mod(w*h,M-2))%M); return 0; }