G - Pre-Order Editorial by inszva


Binary tree is quite easier than a normal tree, so we convert the tree to a binary tree. It is very classic and you can refer to https://www.geeksforgeeks.org/convert-a-generic-treen-array-tree-to-binary-tree/
The only constraint of this binary tree is every node’s right child must be greater than itself. Then we just define \(dp[i][j]\) is the count of the sub tree in the binary tree whose nodes are \(A_i, A_{i+1}, ... , A_{j}\). The transfer is obvious:
\(dp[i][j] = \sum_{k\in[i+1, j+1] \text{ and } (a[k]>a[i] \text{ or } k>j)} dp[i+1][k-1]*dp[k][j]\)
That is to say, enumerate every possible right subtree (include empty tree). The final answer is \(dp[2][n]\) because the root must has no right child in the binary tree.
Code is bellow:

int main() {
    int n;
    cin >> n;
    vector<int> a(n+1);
    for (int i = 1; i <= n; i++) cin >> a[i];
    vector<vector<int>> dp(n+2, vector<int>(n+2, 1));
    for (int len = 2; len <= n; len++) {
        for (int i = 2; i <= n; i++) {
            int j = i+len-1;
            if (j > n) break;
            dp[i][j] = 0;
            for (int k = i+1; k <= j+1; k++) {
                if (k > j || a[k] > a[i])
                    dp[i][j] = (1ll * dp[i][j] + dp[i + 1][k - 1] * dp[k][j] % M) % M;
            }
        }
    }
    cout << dp[2][n] << "\n";
    return 0;
}

posted:
last update: