結果
| 問題 |
No.1685 One by One
|
| コンテスト | |
| ユーザー |
hitonanode
|
| 提出日時 | 2021-08-14 11:49:50 |
| 言語 | Java (openjdk 23) |
| 結果 |
AC
|
| 実行時間 | 1,106 ms / 3,000 ms |
| コード長 | 3,458 bytes |
| コンパイル時間 | 3,058 ms |
| コンパイル使用メモリ | 76,972 KB |
| 実行使用メモリ | 56,092 KB |
| 最終ジャッジ日時 | 2024-06-29 19:29:18 |
| 合計ジャッジ時間 | 26,711 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 46 |
ソースコード
import java.util.*;
public class Main {
static int pow(long x, int k, int md) {
long ret = 1;
while (k > 0) {
if ((k & 1) == 1) {
ret = ret * x % md;
}
x = x * x % md;
k >>= 1;
}
return (int)ret;
}
public class Acl_fac {
long facs[];
long facinvs[];
int md;
public Acl_fac(int N, int md) {
this.facs = new long[N + 1];
this.facinvs = new long[N + 1];
this.md = md;
this.facs[0] = this.facinvs[0] = 1;
for (int i = 1; i <= N; i++) this.facs[i] = this.facs[i - 1] * i % md;
this.facinvs[N] = pow(this.facs[N], md - 2, md);
for (int i = N; i > 0; i--) this.facinvs[i - 1] = this.facinvs[i] * i % md;
}
long ncr(int n, int r) {
if (n < 0 || r < 0 || n < r) return 0;
return this.facs[n] * this.facinvs[r] % this.md * this.facinvs[n - r] % this.md;
}
}
final static int md = 1000000007;
public long run() {
Scanner sc = new Scanner(System.in);
final int N = sc.nextInt();
final int M = sc.nextInt();
Acl_fac fac = new Acl_fac(N + M, md);
final long precalc[] = new long[M + 1];
long ret = 0;
for (int nnonzero = 0; nnonzero <= N; nnonzero++) {
if (nnonzero == 0) precalc[0] = 1;
for (int m = 0; m <= M; m++) {
if (nnonzero + m - 1 >= 0) precalc[m] = fac.ncr(nnonzero + m - 1, nnonzero - 1);
if (m >= 2) {
precalc[m] += precalc[m - 2];
if (precalc[m] >= md) precalc[m] -= md;
}
}
if (N % 2 == 0) {
int half = (N - 1) / 2;
if (nnonzero > half * 2) continue;
long coeff = 0;
for (int npos = 0; npos <= half; npos++) {
int nneg = nnonzero - npos;
if (nneg < 0 || nneg > half) continue;
coeff += fac.ncr(N - 1, npos) * fac.ncr(N - 1 - npos, nneg);
coeff %= md;
}
long tmp = 0;
for (int b0 = 0; b0 <= M; b0++) {
if (M - nnonzero - b0 < 0) continue;
tmp += precalc[M - nnonzero - b0] * (b0 == 0 ? 1 : 2);
tmp %= md;
}
ret += tmp * coeff;
ret %= md;
} else {
long sum = 0;
for (int npos = 0; npos <= N / 2; npos++) {
int nneg = nnonzero - npos;
if (nneg < 0 || nneg > N / 2) continue;
long coeff = 0;
if (M - nnonzero >= 0) coeff += precalc[M - nnonzero];
int m = M - npos - (N - nneg);
if (m >= 0) coeff += precalc[m] * 2;
m = M - (N - nnonzero) - (npos > nneg ? npos : nneg) * 2;
if (m >= 0) coeff += md - precalc[m];
sum += fac.ncr(nnonzero, npos) * coeff;
sum %= md;
}
ret += fac.ncr(N, nnonzero) * sum;
ret %= md;
}
}
return ret;
}
public static void main(String[] args) {
long ret = new Main().run();
System.out.println(ret);
}
}
hitonanode