LOADING

加载过慢请开启缓存 浏览器默认开启

AtCoder Beginner Contest 370

D - Cross Explosion

Problem Statement

There is a grid with $H$ rows and $W$ columns. Let $(i, j)$ denote the cell at the $i$-th row from the top and $j$-th column from the left.
Initially, there is one wall in each cell.
After processing $Q$ queries explained below in the order they are given, find the number of remaining walls.

In the $q$-th query, you are given two integers $R_q$ and $C_q$.
You place a bomb at $(R_q, C_q)$ to destroy walls. As a result, the following process occurs.

  • If there is a wall at $(R_q, C_q)$, destroy that wall and end the process.
  • If there is no wall at $(R_q, C_q)$, destroy the first walls that appear when looking up, down, left, and right from $(R_q, C_q)$. More precisely, the following four processes occur simultaneously:
    • If there exists an $i \lt R_q$ such that a wall exists at $(i, C_q)$ and no wall exists at $(k, C_q)$ for all $i \lt k \lt R_q$, destroy the wall at $(i, C_q)$.
    • If there exists an $i \gt R_q$ such that a wall exists at $(i, C_q)$ and no wall exists at $(k, C_q)$ for all $R_q \lt k \lt i$, destroy the wall at $(i, C_q)$.
    • If there exists a $j \lt C_q$ such that a wall exists at $(R_q, j)$ and no wall exists at $(R_q, k)$ for all $j \lt k \lt C_q$, destroy the wall at $(R_q, j)$.
    • If there exists a $j \gt C_q$ such that a wall exists at $(R_q, j)$ and no wall exists at $(R_q, k)$ for all $C_q \lt k \lt j$, destroy the wall at $(R_q, j)$.
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;

signed main() {
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    int n, m, q;
    cin >> n >> m >> q;

    vector<set<int>> col(m + 1), lin(n + 1);
    vector<vector<bool>> st(n + 1, vector<bool>(m + 1, 0));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) col[j].insert(i), lin[i].insert(j), st[i][j] = 1;
    int res = n * m;
    while (q--) {
        int x, y;
        cin >> x >> y;

        if (st[x][y]) {
            res--, st[x][y] = 0;
            col[y].erase(x), lin[x].erase(y);
            continue;
        }
        auto up = col[y].upper_bound(x), down = up, left = lin[x].upper_bound(y), right = left;
        if (up != col[y].begin()) {
            up--, res--, st[*up][y] = 0;
            col[y].erase(up), lin[*up].erase(y);
        }
        if (down != col[y].end()) {
            res--, st[*down][y] = 0;
            col[y].erase(down), lin[*down].erase(y);
        }
        if (left != lin[x].begin()) {
            left--, res--, st[x][*left] = 0;
            lin[x].erase(left), col[*left].erase(x);
        }
        if (right != lin[x].end()) {
            res--, st[x][*right] = 0;
            lin[x].erase(right), col[*right].erase(x);
        }
    }

    cout << res << endl;

    return 0;
}

E - Avoid K Partition

Problem Statement

You are given a sequence $A = (A_1, A_2, \dots, A_N)$ of length $N$ and an integer $K$.
There are $2^{N-1}$ ways to divide $A$ into several contiguous subsequences. How many of these divisions have no subsequence whose elements sum to $K$? Find the count modulo $998244353$.

Here, “to divide $A$ into several contiguous subsequences” means the following procedure.

  • Freely choose the number $k$ $(1 \leq k \leq N)$ of subsequences and an integer sequence $(i_1, i_2, \dots, i_k, i_{k+1})$ satisfying $1 = i_1 \lt i_2 \lt \dots \lt i_k \lt i_{k+1} = N+1$.
  • For each $1 \leq n \leq k$, the $n$-th subsequence is formed by taking the $i_n$-th through $(i_{n+1} - 1)$-th elements of $A$, maintaining their order.

Here are some examples of divisions for $A = (1, 2, 3, 4, 5)$:

  • $(1, 2, 3), (4), (5)$
  • $(1, 2), (3, 4, 5)$
  • $(1, 2, 3, 4, 5)$
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long

using namespace std;

typedef pair<int, int> PII;
typedef long long LL;

const int mod = 998244353;

signed main() {
    cin.tie(0);
    cout.tie(0);
    ios::sync_with_stdio(0);

    int n, k;
    cin >> n >> k;

    vector<int> a(n + 1), s(n + 1, 0);
    for (int i = 1; i <= n; i ++)
        cin >> a[i], s[i] = s[i - 1] + a[i];

    vector<int> dp(n + 1, 0);
    unordered_map<int, int> tot;
    dp[0] = 1, tot[0] = 1;
    int sum = 1;
    for (int i = 1; i <= n; i ++) {
        dp[i] = (sum - tot[s[i] - k] + mod) % mod;
        (sum += dp[i]) %= mod, (tot[s[i]] += dp[i]) %= mod;
    }

    cout << dp[n] << endl;

    return 0;
}