ABC 362

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

G. Count Substring Query

https://atcoder.jp/contests/abc362/tasks/abc362_g