結果
問題 | No.213 素数サイコロと合成数サイコロ (3-Easy) |
ユーザー | 37zigen |
提出日時 | 2016-05-08 20:47:52 |
言語 | Java21 (openjdk 21) |
結果 |
WA
|
実行時間 | - |
コード長 | 2,600 bytes |
コンパイル時間 | 3,780 ms |
コンパイル使用メモリ | 84,912 KB |
実行使用メモリ | 53,900 KB |
最終ジャッジ日時 | 2024-10-05 10:54:32 |
合計ジャッジ時間 | 3,059 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
ソースコード
package yukicoder; import java.util.Arrays; import java.util.Scanner; public class Main{ public static void main(String[] args){ new Main().solve(); } final long mod =1_000_000_000+7; void solve(){ Scanner sc=new Scanner(System.in); long n=sc.nextLong(); int p=sc.nextInt(); int c=sc.nextInt(); //まず、さいころをP+C個振って和がK個になるパターン数をDPで数える。 long[][] k=new long[p+c+1][13*(p+c)+1]; k[0][0]=1; int[] prime={2,3,5,7,11,13}; int[] composite={4,6,8,9,10,12}; for(int l=0;l<6;l++){ for(int i=0;i<p;i++){ for(int j=0;j<k[0].length;j++){ if(k[i][j]>0){ k[i+1][j+prime[l]]+=k[i][j]; k[i+1][j+prime[l]]%=mod; } } } } for(int l=0;l<6;l++){ for(int i=0;i<c;i++){ for(int j=0;j<k[0].length;j++){ if(k[p+i][j]>0){ k[p+i+1][j+composite[l]]+=k[p+i][j]; k[p+i+1][j+composite[l]]%=mod; } } } } int n_k=k[0].length-1; long[][] A=new long[n_k][n_k]; for(int i=0;i<n_k-1;i++)A[i][i+1]=1; for(int i=0;i<n_k;i++){ A[n_k-1][i]=k[p+c][n_k-i]; } //a[1]~a[n_k]を用意 long[][] a=new long[n_k][1]; for(int i=1;i<k[0].length;i++){ //iはサイコロの目の和 for(int j=0;j>-k[0].length;j--){ //-jから出発した場合 if(i+j>=1){ a[i+j-1][0]+=k[p+c][i]; a[i+j-1][0]%=mod; } } } for(int i=0;i<a.length;i++){ for(int j=i-1;j>=0;j--){ a[i][0]+=(k[p+c][i-j]*a[j][0])%mod; a[i][0]%=mod; } } long[] e=new long[a.length]; for(int i=0;i<k[0].length-1;i++)e[i]=k[p+c][i+1]; long[] aa=new long[a.length]; for(int i=0;i<aa.length;i++)aa[i]=a[i][0]; long ans=solve((int)n,e,aa,mod); System.out.println(ans); } //a[n]=e[0]a[n-1]+e[1]a[n-2]+...+e[K-1]a[n-K]: //a[i]=第i+1項目の値(初期条件) //第N項目を求める。 long solve(int N,long[] e,long[] a,long mod){ int K=e.length; long[] x=new long[K]; long[] y=new long[K]; x[1]=1; y[0]=1; for(int n=N-1;n>0;n>>=1,x=mul(x,x,e,mod)){ if((n&1)==1)y=mul(y,x,e,mod); } long ans=0; for(int i=0;i<K;i++){ ans=(ans+(long)y[i]*a[i])%mod; } return ans; } long[] mul(long[] a,long[] b,long[] e,long mod){ int K=e.length; int i,j; long[] c=new long[2*K]; for(i=0;i<K;i++){ for(j=0;j<K;j++){ c[i+j]=(c[i+j]+a[i]*b[j])%mod; } } for(i=2*K-1;i>=K;i--){ for(j=1;j<=K;j++){ c[i-j]=(c[i-j]+e[j-1]*c[i])%mod; } } long[] d=new long[K]; for(i=0;i<K;i++)d[i]=c[i]; return d; } void tr(Object...o){System.out.println(Arrays.deepToString(o));} }