π§© AtCoder Beginner Contest 393
π§© AtCoder Beginner Contest 393
# Info & Summary
- Date:
2025-02-15
- Completion Status: A β / B β / C β / D β / E β / F β / G β
- Problem Type:
Problem | Type(s) | Data Structure / Algo | π₯ Key Insight / Mark |
---|---|---|---|
E | GCD | Math | π₯ |
F | LIS (Longest monotonically Increasing Subsequence) | DP | π₯ |
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 - Poisonous Oyster

#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s, t;
cin >> s >> t;
if (s == "sick" && t == "sick")
{
cout << 1 << endl;
}
else if (s == "sick" && t == "fine")
{
cout << 2 << endl;
}
else if (s == "fine" && t == "sick")
{
cout << 3 << endl;
}
else
{
cout << 4 << endl;
}
return 0;
}
π B - A..B..C

#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
string s;
cin >> s;
int n = s.size();
int ans = 0;
for (int i = 0; i < n - 2; i++)
{
for (int j = i + 1; j < n - 1; j++)
{
for (int k = j + 1; k < n; k++)
{
if (j - i == k - j && s[i] == 'A' && s[j] == 'B' && s[k] == 'C')
{
ans++;
}
}
}
}
cout << ans << endl;
return 0;
}
π C - Make it Simple

#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n >> m;
set<pair<int, int>> st;
int ans = 0;
for (int i = 0; i < m; i++)
{
int u, v;
cin >> u >> v;
u--;
v--;
if (u == v)
{
ans++;
continue;
}
if (u > v)
{
swap(u, v);
}
if (st.count({u, v}))
{
ans++;
}
else
{
st.insert({u, v});
}
}
cout << ans << endl;
return 0;
}
π D - Swap to Gather

Tips
Fro each 0
in , consider the number of 1
to its left(let it be ) and the number of 1
to its right(let it be ):
- If , it's better to bring
0
to the left of the1
chunk - If , it's better tp bring
0
to the right of the1
chunk
Thus, the answer is the number of for all 0
Let:
- be the number of
0
in - be the number of
1
in , and
For each (), let be the number of 1
s to the right of the -th 0
from the left:
- then
Tips
Let us reinterpret the problem according to the value
First, swapping the same character is meaningless, so the operation in the original problem statement is equivalent to performing one of the following operations against :
- Choose one () with , and decrease by
- Choose one () with , and increase bu
The termination condition is as follows:
- There exist () such that and
One operation changes by one, so clearly at least operations is required, where:
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
string s;
cin >> n >> s;
int c1 = 0;
for (auto c : s)
{
c1 += c == '1';
}
int cur = 0;
long long ans = 0;
for (auto c : s)
{
if (c == '0')
{
ans += min(cur, c1 - cur);
}
else
{
cur++;
}
}
cout << ans << endl;
return 0;
}
Tips
To make all 1
s contiguous, we want to move them into one block, and the optimal block is the one that minimizes total movement distance:
- Store the indices of all
1
s, suppose we have ones at positions: - The best place to group them together is centered around the median position
- If we place
1
s in positions , we can compute the number of operations required
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
string s;
cin >> n >> s;
vector<int> pos;
for (int i = 0; i < n; i++)
{
if (s[i] == '1')
{
pos.push_back(i);
}
}
int k = pos.size();
long long ans = 0;
for (int i = 0; i < k; i++)
{
ans += abs(pos[i] - (pos[k/2] - k / 2 + i));
}
cout << ans << endl;
return 0;
}
π E - GCD of Subset

Tips
One can make the GCD only if:
- is divisible by
- has at least elements divisible by
The answer is the maximum among such
Let be the number of occurrences of in
Let be the number of multiples of in . Here, we will use the notation as " divides n". and have the realtion:
Let be the answer for . realtes as:
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, K;
cin >> N >> K;
vector<int> A(N);
for (int i = 0; i < N; i++)
{
cin >> A[i];
}
int m = *max_element(A.begin(), A.end());
vector<int> s(m + 1), t(m + 1), u(m + 1);
for (auto a : A)
{
s[a]++;
}
for (int d = 1; d <= m; d++)
{
for (int n = d; n <= m; n += d)
{
t[d] += s[n];
}
}
for (int d = 1; d <= m; d++)
{
if (t[d] < K)
{
continue;
}
for (int n = d; n <= m; n += d)
{
u[n] = max(u[n], d);
}
}
for (auto a : A)
{
cout << u[a] << endl;
}
return 0;
}
π F - Prefix LIS Query

LIS (Longest monotonically Increasing Subsequence)
Inspect in the order of to update the following DP
table in-place:
- (): the smallest value of the final term of a length- subsequence that can be extracted from the elements so far, or if there is no such subsequence
Considering the definition of the DP
above, the answer to query turns out to be equal to:
- The maximum such that in the
DP
table when inspecting up to - for each step , finding the answer for all queries with using binary serach
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
vector<int> A(n);
for (int i = 0; i < n; i++)
{
cin >> A[i];
}
vector<vector<pair<int, int>>> qs(n);
for (int i = 0; i < q; i++)
{
int r, x;
cin >> r >> x;
r--;
qs[r].push_back({i, x});
}
vector<int> ans(q);
vector<int> dp(n, 1e9 + 10);
for (int i = 0; i < n; i++)
{
auto it = lower_bound(dp.begin(), dp.end(), A[i]);
*it = A[i];
for (auto [id, x] : qs[i])
{
ans[id] = upper_bound(dp.begin(), dp.end(), x) - dp.begin();
}
}
for (int i = 0; i < q; i++)
{
cout << ans[i] << endl;
}
return 0;
}
π G - Unevenness

Warning
Hard Problems to Tackle Later
// TODO