ある点を最後にシグナルを発信する位置にする。
その点から原点までの間に整数座標の点がいくつあるかを、GCDで求める。
その中から K - 1 コの点を選ぶ組み合わせだけ、選び方が存在する。
原点のから以外にも同様な線分を引くことができるので、その分を掛け算する。
K == 1 の時だけ別処理。
const lli mod = 1000000007; const int N = 2000 + 5; lli nCk[N][N]; void f(void) { for (int i = 0; i < N; ++i) { nCk[i][i] = nCk[i][0] = 1; } for (int i = 0; i < N; ++i) { for (int j = 1; j < i; ++j) { nCk[i][j] = nCk[i - 1][j - 1] + nCk[i - 1][j]; nCk[i][j] %= mod; } } return ; } class Spacetsk { public: int countsets(int L, int H, int K) { if (K == 1) { return (H + 1) * (L + 1); } f(); lli sum = 0; sum += (L + 1) * nCk[H + 1][K]; sum %= mod; for (int i = 1; i <= H; ++i) { for (int j = 1; j <= L; ++j) { int x = __gcd(max(i, j), min(i, j)); sum += nCk[x][K - 1] * (L - j + 1) * 2; sum %= mod; } } return sum; } };