ABC 362
Table of Contents
https://atcoder.jp/contests/abc362
A. Buy a Pen
https://atcoder.jp/contests/abc362/tasks/abc362_a
B. Right Triangle
https://atcoder.jp/contests/abc362/tasks/abc362_b
C. Sum = 0
https://atcoder.jp/contests/abc362/tasks/abc362_c
D. Shortest Path 3
https://atcoder.jp/contests/abc362/tasks/abc362_d
E. Count Arithmetic Subsequences
https://atcoder.jp/contests/abc362/tasks/abc362_e
数列の長さを $L$ とする。
$L=1$ のときは各要素を選ぶ場合の数であるので $N$ 通り。 $L \geq 2$ のときを考える。
$dp(i,L,d)$ を初項 $A_i$、交差差 $d$、長さ $L$ の等差数列の場合の数とすると
\begin{align*} dp(i,L,d) &= \sum_{\substack{j = i+1 \\ A_j - A_i = d}}^{N} dp(j,L-1,d) \end{align*} となる。ここで $\forall d, dp(i,1,d) = 1$ とする。
下記のコードだと計算量は $O(N^3 \log (N^2)) = O(N^3 \log N)$
void solve() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
ll N;
cin >> N;
vll A(N);
rep(i, N) cin >> A[i];
vll diffs;
rep(i, N) rep2(j, i + 1, N) diffs.push_back(A[j] - A[i]);
sort(all(diffs));
diffs.erase(unique(all(diffs)), diffs.end());
ll dsz = diffs.size();
// dp[i][L][d]: i 番目の数字から初めて長さ L、公差 d の数列の場合の数
vector dp(N, vector(N + 1, vector<mint>(dsz)));
rep(i, N) {
rep(di, dsz) {
dp[i][1][di] = 1;
}
}
rep2(L, 2, N + 1) {
rep(i, N) {
rep2(j, i + 1, N) {
auto di = lower_bound(all(diffs), A[j] - A[i]) - diffs.begin();
dp[i][L][di] += dp[j][L - 1][di];
}
}
}
vector<mint> ans = {N};
rep2(L, 2, N + 1) {
mint tmp = 0;
rep(i, N) rep(di, dsz) {
tmp += dp[i][L][di];
}
ans.push_back(tmp);
}
rep(i, N) {
if (i == 0)
cout << ans[i].val();
else
cout << ' ' << ans[i].val();
}
cout << endl;
}
F. Perfect Matching on a Tree
https://atcoder.jp/contests/abc362/tasks/abc362_f