Idea: fcspartakm, preparation: fcspartakm
Tutorial
Tutorial is loading...
Solution (BledDest)
t = int(input())
for i in range(t):
n, a, b = map(int, input().split())
c = n // 3
d = n % 3
print(min((c + 1) * b, c * b + d * a, n * a))
Idea: BledDest, preparation: Neon
Tutorial
Tutorial is loading...
Solution (BledDest)
t = int(input())
for i in range(t):
s = input()
pref2 = 0
suf = 0
for x in s:
if x == '1' or x == '3':
suf += 1
ans = pref2 + suf
for x in s:
if x == '2':
pref2 += 1
if x == '1' or x == '3':
suf -= 1
ans = max(ans, pref2 + suf)
print(len(s) - ans)
2230C - Arrange the Numbers in a Circle
Idea: BledDest, preparation: BledDest
Tutorial
Tutorial is loading...
Solution (BledDest)
t = int(input())
for i in range(t):
n = int(input())
c = list(map(int, input().split()))
s = sum(c)
ones = 0
slots = 0
for x in c:
if x == 1:
ones += 1
else:
slots += x // 2 - 1
if ones == n - 1:
slots += 1
wasted = max(0, ones - slots)
if s - wasted < 3:
print(0)
else:
print(s - wasted)
Tutorial
Tutorial is loading...
Solution (Neon)
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false); cin.tie(0);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> a(n), b(n);
for (auto &x : a) cin >> x, --x;
for (auto &x : b) cin >> x, --x;
vector<int> pa(n + 1, n), pb(n + 1, n), dp(n + 1, n);
long long ans = 0;
for (int i = n - 1; i >= 0; --i) {
pa[a[i]] = i;
pb[b[i]] = i;
if (a[i] == b[i]) {
int x = a[i] + 1;
if (pa[x] == pb[x]) {
dp[i] = dp[pa[x]];
} else {
dp[i] = min(pa[x], pb[x]);
}
}
if (pa[0] != pb[0]) {
ans += min(pa[0], pb[0]) - i;
} else {
ans += dp[pa[0]] - i;
}
}
cout << ans << '\n';
}
}
Idea: adedalic, preparation: adedalic
Tutorial
Tutorial is loading...
Solution (adedalic)
import bisect
import sys
input = sys.stdin.readline
INF = int(1e9) + 7
A = int(1e6) + 3
n = int(input())
a = [list(map(int, input().split())) for i in range(2)]
minVal = [[INF] * A for i in range(2)]
pMin = [[INF] * A for i in range(2)]
sMin = [[INF] * A for i in range(2)]
for k in range(2):
for i in range(n):
minVal[k][a[k][i]] = min(minVal[k][a[k][i]], a[k ^ 1][i])
for v in range(A - 1):
pMin[k][v + 1] = min(pMin[k][v], minVal[k][v])
for v in range(A - 2, -1, -1):
sMin[k][v] = min(sMin[k][v + 1], minVal[k][v])
mid = 0
for i in range(n):
if a[0][mid] + a[1][mid] > a[0][i] + a[1][i]:
mid = i
m = int(input())
t = [list(map(int, input().split())) for i in range(3)]
def I(val, l, r):
if val < l:
return 0
return min(val, r)
ans = []
for id in range(m):
cur = I(a[0][mid], t[0][id], t[0][id] + t[2][id]) + I(a[1][mid], t[1][id], t[1][id] + t[2][id])
for k in range(2):
pos_l = t[k][id]
pos_r = min(A - 1, t[k][id] + t[2][id])
if pMin[k][pos_l] < INF:
cur = min(cur, I(pMin[k][pos_l], t[k ^ 1][id], t[k ^ 1][id] + t[2][id]))
if sMin[k][pos_r] < INF:
cur = min(cur, pos_r + I(sMin[k][pos_r], t[k ^ 1][id], t[k ^ 1][id] + t[2][id]))
ans.append(cur)
print("\n".join(map(str, ans)))
Idea: BledDest, preparation: BledDest
Tutorial
Tutorial is loading...
Solution (BledDest)
#include<bits/stdc++.h>
using namespace std;
const int N = 200043;
const int K = 3;
const int LN = 20;
vector<int> g[N];
int p[N];
pair<int, int> dp_down[N][K];
int dp_up[N];
int q_index;
int ans[N];
int f[N];
void upd_down(int idx, pair<int, int> p)
{
if(dp_down[idx][K - 1] < p)
{
dp_down[idx][K - 1] = p;
int j = K - 1;
while(j != 0)
{
if(dp_down[idx][j - 1] < dp_down[idx][j])
{
swap(dp_down[idx][j - 1], dp_down[idx][j]);
j--;
}
else break;
}
}
}
void upd(pair<int, int>& p, int x)
{
if(p.second < x) p.second = x;
if(p.first < p.second) swap(p.first, p.second);
}
int get_cur(int x)
{
pair<int, int> cur_ans = {0, 0};
for(int i = 0; i < K; i++)
if(dp_down[x][i].second != f[x])
upd(cur_ans, dp_down[x][i].first);
if(f[x] != -1)
upd(cur_ans, dp_up[x]);
return cur_ans.second + 1;
}
int get_full(int x)
{
pair<int, int> cur_ans = {0, 0};
for(int i = 0; i < K; i++)
upd(cur_ans, dp_down[x][i].first);
upd(cur_ans, dp_up[x]);
return cur_ans.second + 1;
}
void dfs1(int x, int parent = -1)
{
p[x] = parent;
for(auto y : g[x])
{
if(y > q_index) continue;
if(y != parent)
{
dfs1(y, x);
upd_down(x, make_pair(get_cur(y), y));
}
}
}
void dfs2(int x)
{
if(p[x] != -1)
dp_up[x] = get_cur(p[x]);
for(auto y : g[x])
{
if(y > q_index) continue;
if(y != p[x])
{
f[x] = y;
dfs2(y);
f[x] = -1;
}
}
}
int get_ans(int x)
{
q_index = x + 2;
for(int i = 1; i <= q_index; i++)
{
dp_up[i] = 0;
for(int j = 0; j < K; j++)
dp_down[i][j] = {0, -1};
p[i] = -1;
f[i] = -1;
}
dfs1(1);
dfs2(1);
int ans = 1;
for(int i = 1; i <= q_index; i++)
ans = max(ans, get_full(i));
return ans;
}
void rec(int l, int r, int L, int R)
{
if(l >= r) return;
if(L == R)
{
for(int i = l; i < r; i++)
ans[i] = L;
return;
}
int mid = (l + r) / 2;
ans[mid] = get_ans(mid);
rec(l, mid, L, ans[mid]);
rec(mid + 1, r, ans[mid], R);
}
void solve()
{
int q;
cin >> q;
for(int i = 0; i < q; i++)
{
int x;
cin >> x;
g[x].push_back(i + 2);
g[i + 2].push_back(x);
}
rec(0, q, 1, LN);
for(int i = 0; i < q; i++)
cout << ans[i] << " ";
cout << "\n";
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
int t = 1;
for(int i = 0; i < t; i++)
solve();
return 0;
}








this educational round felt a bit harder than previous edcuational rounds…
I created video editorial for D. Good Schedule.
thank you for this beautiful round.
Why the rating isn't updated yet?
add it in contest material or annoucement blog i had been waiting for this
How long do we need to wait for the rating to update ?
1 2 1 1 2 2
in D if we see what they watched it will look like
1 2 null
1 2 null
so all three days are same work
then why only 4 segmenst why not 6 segment ??
i am confused please help me
The segment [2, 3] is invalid — on day 2, the episodes are (2, 2) so they will both watch nothing. Then on day 3 the episodes are (1, 2) so only one of them will watch episode 1, which fails the requirements. You can similarly see that [1, 3] is invalid, so the total number of valid segments is 6-2 = 4.
the problems where amazing this round but the pretests where kind of weak but yea overall top tier
Another approach to Problem D uses binary lifting.
The general idea of my solution is fix the endpoint $$$l$$$ and count the valid right endpoints $$$r$$$(for both arrays)
We have the following observation: If the segment $$$[l, r]$$$ is valid, then the segment $$$[l, r - 1]$$$$$$(l \lt r)$$$ is also valid. So, we can consider an approach of finding the largest position that satisfies the condition, and then add $$$r - l + 1$$$ to the answer, where $$$r$$$ is the largest valid position.
Consider the subarray $$$[l, r]$$$, If $$$a[l] = b[l] = 1$$$, then position $$$l$$$ can be treated as a valid starting point for both arrays. In other cases, we need to find the first position greater than $$$l$$$(which equals $$$1$$$) in both arrays $$$a$$$ and $$$b$$$, denoted by $$$\text{pos}_a$$$ and $$$\text{pos}_b$$$ respectively. If $$$\text{pos}_a \ne \text{pos}_b$$$, then the two people will not watch the first movie at the same time. Therefore, the valid positions for $$$l$$$ range from $$$l$$$ to $$$\min(\text{pos}_a, \text{pos}_b) - 1$$$. Otherwise, the segment from $$$l$$$ to $$$\text{pos}_a$$$ ($$$\text{pos}_a = \text{pos}_b$$$) is still valid. Let $$$next_a$$$ be the nearest position to the right of $$$pos_a$$$ that has value $$$2$$$, and let $$$next_b$$$ be the nearest position to the right of $$$pos_b$$$ that has value $$$2$$$. Thus, for Alice and Bob to both watch the second movie, we must have $$$next_a = next_b$$$. From this, we have the idea of finding a movie (each movie corresponds to a position) such that Alice and Bob watch it together as the final one. Let the last movie watched be $$$p$$$, located at index $$$idx$$$ in both arrays. If there is no occurrence of $$$p + 1$$$ in both arrays at any position greater than $$$idx$$$, then $$$r = n$$$. Otherwise, we can process like conditions $$$\text{pos}_a \ne \text{pos}_b$$$, use $$$n$$$ vector contains index of value and use binary search.
Now, we consider each joint movie watch as a “jump” on the array. Thus, we need to determine how many steps we can jump in total. To solve this problem, we define an array $$$isNext[idx]$$$, which represents the next position we can jump to. Note that $$$isNext$$$ is only meaningful for indices $$$idx$$$ such that $$$a_{idx} = b_{idx}$$$. Let $$$p = a_{idx} = b_{idx}$$$. Then, $$$isNext[idx]$$$ is true if the first position greater than $$$idx$$$ in array $$$a$$$ with value $$$p + 1$$$ is equal to the first position greater than $$$idx$$$ in array $$$b$$$ with value $$$p + 1$$$. For the brute-force approach, we can keep jumping until no further moves are possible. However, we can improve by using binary lifting on the $$$isNext$$$ array.
Time complexity is $$$O(n \log n)$$$.
I also followed this approach, my submission: 375149035
One more approach that uses a different logic of DP: Iterate day i in increasing order. Let dp[i][j] be the number of valid segments ending at i and have watched episodes 1 to j.
Firstly, set dp[i][0] to dp[i-1][0] + 1 (a new valid starting point) If A[i] == B[i], we set dp[i][A[i]] to dp[i-1][A[i]] + dp[i-1][A[i]-1] and set dp[i][A[i]-1] to 0. If A[i] != B[i], set dp[i][A[i]] and dp[i][B[i]] to 0. For all other unchanged dp[i][j], follow the same value as dp[i-1][j].
The answer will be the sum of all dp[i][j] values
However, this is clearly O(N^2), but we can actually cut the first state. Then, there will be O(1) values of dp[j] being changed. In addition, maintain sum as the current sum of dp[j] values, and add sum to ans at the end of each iteration for i.
375700493
Hopefully my explanation isn't that bad
I did this too, but why is it O(N^2)?
We loop from 1 to N, and each update of dp is O(1), so surely O(N) overall?
Sorry if this is a stupid question.
nice problems
what could be the possible rating for D?
B only needs to be computed at the odd and even nodes; it does not need to be computed at every point.
O(N^2) I am really frustrated. Why my solution for problem B is incorrect? Apart from TLE what is wrong in the logic? See we will need to remove all the 4s. We then need to make sure that no 2 comes after 1 or 3. So we take the minimum of the (one + threes) and twos and then add it to number of 4s. What is wrong in this? I also have O(n) solution for the same problem. Please someone help me out. God bless you!
i am also stuck on same question and did same as you
hey why my code for digit string is wrong in second test
i dont get it what is going wrong with my code
Try case 121222, or 1121222.
For the first case: Tracing your solution it seems it removed the 2 (2nd index) and then the 1s (indexes 1, 3).
Thanks , now i understand , where i was wrong
import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map.Entry; import java.util.PriorityQueue; import java.util.Scanner;
public class helloworld {
if(sb.charAt(i) == '4' ) { ans++;
} if(sb.charAt(i) == '1') { check1 = true; } if(sb.charAt(i) == '2' && check1 == true ) { check12 = true; } if(sb.charAt(i) == '2' && check3 == true ) { check32 = true; } if(sb.charAt(i) == '3') { check3 = true; }
} for(int i = 0; i < s.length(); i++) { if(check12 == true && s.charAt(i) == '1' && i != s.length() -1 ) { count1++; } if((check12 == true || check32 == true) && s.charAt(i) == '2' &&i != 0 ) { count2++; } if(check32 == true && s.charAt(i) == '3' && i != s.length() -1) { count3++; } }
} ~~~~~ what is wrong with this code
~~~~~ // this is code
import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map.Entry; import java.util.PriorityQueue; import java.util.Scanner;
public class helloworld {
public static void main(String[] args) { Scanner scn = new Scanner(System.in);
int t = scn.nextInt(); while(t > 0) { String s = scn.next(); StringBuilder sb = new StringBuilder(s); int ans = 0; boolean check1 = false; boolean check12 = false; boolean check32 = false; boolean check3 = false; int count1 = 0; int count2 = 0; int count3 =0 ; for(int i = 0; i < s.length(); i++) {if(sb.charAt(i) == '4' ) { ans++;
} if(sb.charAt(i) == '1') { check1 = true; } if(sb.charAt(i) == '2' && check1 == true ) { check12 = true; } if(sb.charAt(i) == '2' && check3 == true ) { check32 = true; } if(sb.charAt(i) == '3') { check3 = true; }
} for(int i = 0; i < s.length(); i++) { if(check12 == true && s.charAt(i) == '1' && i != s.length() -1 ) { count1++; } if((check12 == true || check32 == true) && s.charAt(i) == '2' &&i != 0 ) { count2++; } if(check32 == true && s.charAt(i) == '3' && i != s.length() -1) { count3++; } }
} } ~~~~~ what is wrong with this code
Can someone please explain this again?
$$$min_{ p_i \lt tp_j } I_c(i, j) == min( min_{ p_i \lt tp_j } I_c(i, j), min_{p_k \gt = tp_j}(I_c(k, j) + I_p(k, j) )$$$ ?
It's alright now. I understand.
Another approach for D: 375158478
guys , please , dislike my comment , please :)
I solved 4 questions, but it is still showing skipped on my end and my rating has not been updated.
For problem E, I have made 2 submissions 379607342 and 379607834. The first submission has a typo in case3, due to which binary search is performed on a different array than the intended one. However, both of these solutions have passed the system tests.
The first solution should give a Wrong Answer in cases where the optimal answer comes strictly from an index $$$i$$$ where $$$p_i \ge tp_j + d_j$$$.
One of those test cases is:
The expected output is 42 but this 379607342 submission gives output as 60.
C has every type of test case that one can think of
Editorial of E blew my mind :)