π§© AtCoder Beginner Contest 378
November 2, 2024About 4 min
π§© AtCoder Beginner Contest 378
# Info & Summary
- Date:
2024-11-02
- Completion Status: A β / B β / C β / D β / E β / F β / G β
- Problem Type:
Problem | Type(s) | Data Structure / Algo | π₯ Key Insight / Mark |
---|---|---|---|
D | DFS | DFS | βπ₯ |
E | Math | Fenwick Tree | π§ π οΈπ |
F | Tree/Graph | DP/LCA | π |
G | Math | RobinsonβSchensted correspondence | π |
Details
Emoji | Label | Meaning |
---|---|---|
β | Important | Problem is strategically useful or has reusable patterns |
π₯ | Must master | Classic problem or technique that appears often and is worth mastering |
β οΈ | Reattempt | You attempted but failed; worth reviewing and solving again |
π§ | New to me | Introduced a new idea, technique, or pattern you hadnβt seen before |
π οΈ | Template | You built or improved a code template from solving this problem |
π | Too hard now | Beyond current ability to understand/solve; revisit after more practice |
π A - Pairing

#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
vector<int> cnt(4);
for (int i = 0; i < 4; i++)
{
int A;
cin >> A;
A--;
cnt[A]++;
}
int ans = 0;
for (int i = 0; i < 4; i++)
{
ans += cnt[i] / 2;
}
cout << ans << endl;
return 0;
}
π B - Garbage Collection

#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
vector<int> q(N), r(N);
for (int i = 0; i < N; i++)
{
cin >> q[i] >> r[i];
}
int Q;
cin >> Q;
for (int i = 0; i < Q; i++)
{
int t, d;
cin >> t >> d;
t--;
cout << d + (r[t] - d % q[t] + q[t]) % q[t] << endl;
}
return 0;
}
π C - Repeating

#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
vector<long long> A(N), B(N, -1);
map<long long, int> mp;
for (int i = 0; i < N; i++)
{
cin >> A[i];
if (mp.count(A[i]))
{
B[i] = mp[A[i]];
}
mp[A[i]] = i + 1;
}
for (int i = 0; i < N; i++)
{
cout << B[i] << " \n"[i == N - 1];
}
return 0;
}
π D - Count Simple Paths

#include <bits/stdc++.h>
using namespace std;
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int H, W, K;
cin >> H >> W >> K;
vector<string> grid(H);
for (int i = 0; i < H; i++)
{
cin >> grid[i];
}
int ans = 0;
vector<vector<bool>> vis(H, vector<bool>(W));
auto dfs = [&](auto &&self, int i, int j, int k) -> void
{
if (k == 0)
{
ans++;
return;
}
vis[i][j] = true;
for (int d = 0; d < 4; d++)
{
int nx = i + dx[d];
int ny = j + dy[d];
if (nx < 0 || ny < 0 || nx >= H || ny >= W)
{
continue;
}
if (grid[nx][ny] == '#')
{
continue;
}
if (vis[nx][ny])
{
continue;
}
self(self, nx, ny, k - 1);
}
vis[i][j] = false;
};
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
{
if (grid[i][j] == '.')
{
dfs(dfs, i, j, K);
}
}
}
cout << ans << endl;
return 0;
}
π E - Mod Sigma Problem

Tips
The typical approach to represent subarray sums employs cumulative sums
Let be the cumulative sums (modulo ) of the sequence
Then the sought value can be:
Since , we can write as:
which no longer involves mod
Tips
Let : the number of with and apply the equation above to rewrite the sought value as:
Then is a cumulative sum of , which can be evaluated easily
Tips
All that left is to find for fast enough for each
can be computed using a Fenwick Tree
Here, if we define as the number of with , we can compute by the following algorithm:
- Initialize with
- For each , do the following:
- Compute
- Add to
The overall complexity is
#include <bits/stdc++.h>
using namespace std;
template <typename T>
struct Fenwick
{
int n;
vector<T> a;
Fenwick(int n_ = 0)
{
init(n_);
}
void init(int n_)
{
n = n_;
a.assign(n, T{});
}
void add(int x, const T &v)
{
for (int i = x + 1; i <= n; i += i & -i)
{
a[i - 1] = a[i - 1] + v;
}
}
T sum(int x)
{
T ans{};
for (int i = x; i > 0; i -= i & -i)
{
ans = ans + a[i - 1];
}
return ans;
}
T rangeSum(int l, int r)
{
return sum(r) - sum(l);
}
int select(const T &k)
{
int x = 0;
T cur{};
for (int i = 1 << __lg(n); i; i /= 2)
{
if (x + i <= n && cur + a[x + i - 1] <= k)
{
x += i;
cur = cur + a[x - 1];
}
}
return x;
}
};
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, M;
cin >> N >> M;
vector<long long> A(N);
for (int i = 0; i < N; i++)
{
cin >> A[i];
}
vector<long long> pre(N + 1);
for (int i = 0; i < N; i++)
{
pre[i + 1] = pre[i] + A[i];
}
long long ans = 0;
for (int i = 0; i <= N; i++)
{
pre[i] %= M;
// \sum_{r = 1}^{N}(S_r \times r)
ans += pre[i] * i;
// \sum_{r = 1}^{N}\sum_{l = 1}^{r}S_{l - 1}
ans -= pre[i] * (N - i);
}
// count how many values to the left of index i are greater than pre[i]
Fenwick<int> fen(N + 1);
// in descending order
vector<int> p(N + 1);
iota(p.begin(), p.end(), 0);
sort(p.begin(), p.end(), [&](int i, int j)
{
if (pre[i] != pre[j])
{
return pre[i] > pre[j];
}
return i > j; });
// Then we sweep from largest to smallest, using Fenwick tree to count how many j < i have already been added
for (auto i : p)
{
// M \times X_r
ans += 1ll * fen.sum(i) * M;
fen.add(i, 1);
}
cout << ans << endl;
return 0;
}
π F - Add One Edge 2

Warning
Hard Problems to Tackle Later
// TODO
π G - Everlasting LIDS

Warning
Hard Problems to Tackle Later
// TODO