Code
#include <atcoder/modint>
#include <bits/stdc++.h>
using namespace std;
using namespace atcoder;
using mint = modint998244353;
// Tip: Instead of dividing by 2 everytime, we precompute the inverse, and
// multiply by it. In other words, we directly multiply by 1/2, since this is
// a constant and will be used in multiple places.
const mint p = mint(1) / 2;
void solve(int n) {
// dp[l][r] is the answer for the person for whom l people are standing at
// the front and r people are standing at the back.
vector<vector<mint>> dp(n + 1, vector<mint>(n + 1, 0));
dp[0][0] = 1;
// Solve on each anti-diagonal.
// We are solving in increasing order of k, where k = l + r.
for (int k = 1; k <= n; k++) {
// Assume that dp[0][k] = x
// At each step, we make sure that the answer is Ax + B.
mint A = 1, B = 0;
int i = 1, j = k - 1;
while (i <= n && j >= 0) {
// dp[i][j] = dp[i - 1][j]/2 + dp[i - 1][j + 1]/2;
// The answer for dp[i - 1][j] is already computed, we can use it.
A = A * p;
B = (B + dp[i - 1][j]) * p;
i++;
j--;
}
// 2*x = A*x + B
// x = B/(2 - A)
dp[0][k] = B / (mint(2) - A);
// Now, backtrack and populate all values.
i = 1, j = k - 1;
while (i <= n && j >= 0) {
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j + 1]) * p;
i++;
j--;
}
}
int front = 0, back = n - 1;
for (int i = 1; i <= n; i++) {
cout << dp[front][back].val() << " ";
front++;
back--;
}
cout << "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
solve(n);
return 0;
}
#include <atcoder/modint>
#include <bits/stdc++.h>
using namespace std;
using namespace atcoder;
using mint = modint998244353;
// Tip: Instead of dividing by 2 everytime, we precompute the inverse, and
// multiply by it. In other words, we directly multiply by 1/2, since this is
// a constant and will be used in multiple places.
const mint p = mint(1) / 2;
void solve(int n) {
// dp[l][r] is the answer for the person for whom l people are standing at
// the front and r people are standing at the back.
vector<vector<mint>> dp(n + 1, vector<mint>(n + 1, 0));
dp[0][0] = 1;
// Solve on each anti-diagonal.
// We are solving in increasing order of k, where k = l + r.
for (int k = 1; k <= n; k++) {
// Assume that dp[0][k] = x
// At each step, we make sure that the answer is Ax + B.
mint A = 1, B = 0;
int i = 0, j = k;
i++;
j--;
while (i <= n && j >= 0) {
// dp[i][j] = dp[i - 1][j]/2 + dp[i - 1][j + 1]/2;
// The answer for dp[i - 1][j] is already computed, we can use it.
A = A * p;
B = (B + dp[i - 1][j]) * p;
i++;
j--;
}
// 2*x = A*x + B
// x = B/(2 - A)
dp[0][k] = B / (mint(2) - A);
// Now, backtrack and populate all values.
i = 0, j = k;
i++;
j--;
while (i <= n && j >= 0) {
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j + 1]) * p;
i++;
j--;
}
}
// Now, all values in the upper triangle is populated correctly.
// Let's fix the lower triangle now.
// This isn't really needed, as we don't use the lower triangle.
// But better safe than sorry.
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= n; j++) {
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j + 1]) * p;
}
}
int front = 0, back = n - 1;
for (int i = 1; i <= n; i++) {
cout << dp[front][back].val() << " ";
front++;
back--;
}
cout << "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
solve(n);
return 0;
}
#include <atcoder/modint>
#include <bits/stdc++.h>
using namespace std;
using namespace atcoder;
// Tip: Avoid modular divison as much as possible.
using mint = modint998244353;
const mint p = mint(2);
void solve(int n) {
// dp[l][r] is the answer for the person for whom l people are standing at
// the front and r people are standing at the back.
vector<vector<mint>> dp(n + 1, vector<mint>(n + 1, 0));
dp[0][0] = 1;
// Solve on each anti-diagonal.
// We are solving in increasing order of k, where k = l + r.
for (int k = 1; k <= n; k++) {
// Assume that dp[0][k] = x
// At each step, we make sure that the answer is Ax + B.
mint A = 1, B = 0;
int i = 0, j = k;
i++;
j--;
while (i <= n && j >= 0) {
// dp[i][j] = dp[i - 1][j]/2 + dp[i - 1][j + 1]/2;
// The answer for dp[i - 1][j] is already computed, we can use it.
// Combining 2 divisons into one to save time.
A = A / p;
B = (B + dp[i - 1][j]) / p;
i++;
j--;
}
// 2*x = A*x + B
// x = B/(2 - A)
dp[0][k] = B / (mint(2) - A);
// Now, backtrack and populate all values.
i = 0, j = k;
i++;
j--;
while (i <= n && j >= 0) {
// Combining 2 divisons into one to save time.
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j + 1]) / p;
i++;
j--;
}
}
// Now, all values in the upper triangle is populated correctly.
// Let's fix the lower triangle now.
// This isn't really needed, as we don't need the lower triangle.
// But adding this results in TLE.
// for (int i = 1; i <= n; i++) {
// for (int j = 0; j <= n; j++) {
// dp[i][j] = (dp[i - 1][j] + dp[i - 1][j + 1]) / p;
// }
// }
int front = 0, back = n - 1;
for (int i = 1; i <= n; i++) {
cout << dp[front][back].val() << " ";
front++;
back--;
}
cout << "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
solve(n);
return 0;
}
#include <atcoder/modint>
#include <bits/stdc++.h>
using namespace std;
using namespace atcoder;
using mint = modint998244353;
const mint p = mint(2);
void solve(int n) {
// dp[l][r] is the answer for the person for whom l people are standing at
// the front and r people are standing at the back.
vector<vector<mint>> dp(n + 1, vector<mint>(n + 1, 0));
dp[0][0] = 1;
// Solve on each anti-diagonal.
// We are solving in increasing order of k, where k = l + r.
for (int k = 1; k <= n; k++) {
// Assume that dp[0][k] = x
// At each step, we make sure that the answer is Ax + B.
mint A = 1, B = 0;
int i = 0, j = k;
i++;
j--;
while (i <= n && j >= 0) {
// dp[i][j] = p*dp[i - 1][j] + p*dp[i - 1][j + 1]
// The answer for dp[i - 1][j] is already computed, we can use it.
A = A / p;
B = (B + dp[i - 1][j]) / p;
i++;
j--;
}
// 2*x = A*x + B
// x = B/(2 - A)
dp[0][k] = B / (mint(2) - A);
// Now, backtrack and populate all values.
i = 0, j = k;
i++;
j--;
while (i <= n && j >= 0) {
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j + 1]) / p;
i++;
j--;
}
}
// Now, all values in the upper triangle is populated correctly.
// Let's fix the lower triangle now.
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= n; j++) {
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j + 1]) / p;
}
}
int front = 0, back = n - 1;
for (int i = 1; i <= n; i++) {
cout << dp[front][back].val() << " ";
front++;
back--;
}
cout << "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
solve(n);
return 0;
}
Always precompute 1/p
if it’s a constant and will be used a lot in later stages.