Блог пользователя SpyrosAliv

Автор SpyrosAliv, 18 месяцев назад, По-английски

Thanks for the participation. I hope you enjoyed the problems, or at the very least learned something new.

Rate Contest Quality
Rate Contest Difficulty
Favorite Problem
Worst Problem

The codes will be posted after the hacking phase is over. Codes have been posted.

Problem A — DR. TC

(Author & Analysis: SpyrosAliv)

Solution
Implementation
Rate the Problem

Problem B — ST. CHROMA

(Author & Analysis: SpyrosAliv)

Solution
Implementation
Rate the Problem

Problem C — CHERRY BOMB

(Author & Analysis: SpyrosAliv)

Solution
Implementation
Rate the Problem

Problem D — IGOR / FLOWER BOY

(Author: cry, Analysis: cowthecow)

Solution
Implementation
Rate the Problem

Problem E — WOLF

(Author: SpyrosAliv, Analysis: cowthecow)

Solution
Implementation
Rate the Problem

Problem F — GOBLIN

(Author & Analysis: SpyrosAliv)

Solution
Implementation (Prefix Sums)
Implementation (DSU)
Rate the Problem

Problem G1 — BAUDELAIRE (Easy Version)

(Author & Analysis: SpyrosAliv)

Solution
Implementation
Rate the Problem

Problem G2 — BAUDELAIRE (Hard Version)

(Author & Analysis: SpyrosAliv)

Solution
Implementation
Rate the Problem
Разбор задач Codeforces Round 1020 (Div. 3)
  • Проголосовать: нравится
  • +153
  • Проголосовать: не нравится

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +23 Проголосовать: не нравится

Thank you for the good contest

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +15 Проголосовать: не нравится

the best d3 of 2025 maybe :heart:

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +19 Проголосовать: не нравится

The question is great. Thank you for providing an exciting competition.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +2 Проголосовать: не нравится

Problem statement of E was hilarious

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +4 Проголосовать: не нравится

Problem D messed me up for good, however I had fun. It was a great contest, shout out to the team who made it possible.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

enjoyed the problemset <3

»
18 месяцев назад, скрыть # |
← Rev. 4  
Проголосовать: нравится +27 Проголосовать: не нравится

Problem G2 is also solvable in $$$n + 58$$$ queries.

First, we use $$$n$$$ queries to find $$$f(u)$$$ of each node.

For each centroid $$$u$$$, toggle it. Then, to find the subtree that has the root, perform a binary search by querying the new value and comparing it with the value we initially queried. If the root is in the subtree $$$v$$$, then toggling $$$u$$$ does not affect our next queries when searching in subtree $$$v$$$.

To recover the answer, we can compute it from the values we initially queried, then toggle all the toggled nodes.

This process uses $$$\log n + (\log n + \log(\frac{n}{2}) + \dots + 1)$$$ additional queries, which adds up to about $$$58$$$ queries when $$$n = 1000$$$.

My submission: 317066028

  • »
    »
    18 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится +8 Проголосовать: не нравится

    orzorzorzorz

  • »
    »
    18 месяцев назад, скрыть # ^ |
    ← Rev. 6  
    Проголосовать: нравится +10 Проголосовать: не нравится

    I think the argument can be modified to get $$$n + O(\log n)$$$

    total queries.

    At each stage of the binary search, define a potential to be the number of candidates that we have so far for the root, i.e., the sum of the sizes of all sub-trees that we binary search on.

    Suppose we have narrowed down the root to one of $$$k$$$ sub-trees of sizes $$$x_1 \geq x_2 \geq \dots x_k$$$ and that $$$x_1 + x_2 + \dots x_k = m$$$

    . In our algorithm, we choose the smallest prefix whose sum is at least $$$m/4$$$ and query if the root is in one of these subtrees. To analyze the query complexity, let's consider the following cases.

    Case 1: $$$x_1 \leq m/2$$$ . In this case, the subset that we query has total size at least $$$m/4$$$ (by definition) and at most $$$m/2 + m/4 \leq 3m/4$$$. Hence, regardless of where the root lies, the number of potential candidates reduces to $$$3m/4$$$.

    Case 2: $$$x_1 \geq m/2$$$ In this case, we check whether the root is in the sub-tree $$$x_1$$$. If the answer is false, then we are down to at most $$$m/2$$$ candidates. If the answer is true, then in the next query we will be in Case 1 after centroid decomposition of the root at $$$x_1$$$.

    Hence, after every two binary searches, the number of candidates reduces by a factor of $$$3/4$$$. This leads to at most $$$n + 2 \cdot \log_{4/3} n$$$ queries which is at most $$$n + 48$$$ for $$$n \leq 1000$$$. (Sigh, the $$$48$$$ is much larger than I was hoping and sadly not dramatically different from $$$58$$$).

    I modified your submission and added an assert and this passes all cases.

    For analysis, I suspect the $$$1/4$$$ factor is optimal, because we only have a guarantee of at most $$$1/2$$$ after centroid decomposition, so using say a different factor $$$\lambda$$$ the best we could get is $$$\max(\lambda, 1/2 - \lambda)$$$ which is minimized at $$$\lambda = 1/4$$$. Not sure if the constant can be made better.

  • »
    »
    18 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    the same works if we find the root first and then calculate our answer

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +1 Проголосовать: не нравится

E is a nice problem, But I made a stupid mistake on it.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +14 Проголосовать: не нравится

For problem D, Can we do binary search on the beauty of flower that needs to be inserted? I was trying to solve it this way but WA on Test case 2.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

Best div3 till now for me, ig. Couldn't get time to solve D, but yeah, understood what happened :D

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

in the E problem, it says "For each query, output the minimum integer d that Cow the Nerd must choose so that f(l,r,k) can be successful", but in second test case, 1st query, it says answer is 2 because we have changed 2 elements, but the value of d should be 3 because we are changing elements before index 3, how is answer equal to 2? what do we have to answer? the number of minimum elements that are changed or the minimum index before which numbers are changed?

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

Thanks for a great contest!

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

I liked C.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +6 Проголосовать: не нравится

I misread E which made it buffed , i want to suggest it and its approach anyways.

basically consider the rearrangements to be allowed in only $$$l$$$ and $$$r$$$ rather than $$$1$$$ to $$$n$$$ that way you will have to use a segment tree to obtain the amount of elements greater and less than $$$x$$$ in the given range, and then use same logic.

Time complexity : $$$n *(log{n})^2$$$

Space complexity : $$$n *log{n}$$$

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +97 Проголосовать: не нравится

You can also solve G1 in $$$n + 2$$$ queries. First query node 1, if the result is 1 or -1 then it is the root and you can find all other node values in $$$n - 1$$$ queries. Otherwise, if the result is not 0, toggle it so that it is. Now query all nodes other than node 1: if it is the root, then its value is clearly equal to the query result, and if it is not the root, then the query result is its value + (value of node 1 + value of root) = its value + 0 = its value. Finally we can find the value of node 1 in 2 extra queries if we didn't need to toggle it earlier.

Submission: 317084942

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

How come so many solutions of Problem C are being hacked? mine too got hacked :(

»
18 месяцев назад, скрыть # |
← Rev. 3  
Проголосовать: нравится +6 Проголосовать: не нравится

After having non finite amount of testers too many mistakes in problem statements.Wasted too much time. Disappointed :(

  • »
    »
    18 месяцев назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится +3 Проголосовать: не нравится

    It's true, there were a lot of last minute changes, so the testers didn't get to see the latest versions. I apologize for any inconveniences caused, and I hope they didn't affect the quality and enjoyability of the round too much.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

E is a good problem, I like it.

»
18 месяцев назад, скрыть # |
← Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

implementations are not loading so can anyone check my code for D? I used prefix and suffix arrays which record till which flower from the beginning we can get and from which flower to the end we can get resp. Then iterate for each flower and keep minimum valid one to plant. Failed on test2. https://codeforces.me/contest/2106/submission/317078271

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +8 Проголосовать: не нравится

I'm newbie, but E is the most interesting binary search problem I've ever seen.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится -27 Проголосовать: не нравится

can any one tell me that is

Problem C — CHERRY BOMB can't be done by binary Search

I try but fails on some test case

this is my logic


public int binarySearch(long sum,long arr[],int idx) { int left=idx; int right=arr.length; while (right-left>1) { int mid = (right+left)/2; long val = arr[mid]; if(sum>=val) { left=mid; sum+=val; } else { right=mid; } } return left; } public boolean isCons(Integer a[],Integer b[],int mid,int k) { int sum = a[0]+mid; int n = a.length; for(int i=0;i<n;i++) { int num1 = a[i]; //a+x=sum //x = sum-a int diff = sum-num1; if(diff<0 || diff>k) { return false; } } return true; } public boolean isCons1(Integer a[],Integer b[],int sum,int k) { int n = a.length; for(int i=0;i<n;i++) { int num1 = a[i]; //a+x=sum //x = sum-a int diff = sum-num1; if(diff<0 || diff>k) { return false; } } return true; } void solve() { int n = sc.nextInt(); int k = sc.nextInt(); Integer a[] = sc.nextIntegerArray(n); Integer b[] = sc.nextIntegerArray(n); int sum = Integer.MIN_VALUE; for(int i=0;i<n;i++) { int num1 = a[i]; int num2 = b[i]; if(num2!=-1) { if(sum!=Integer.MIN_VALUE) { if(sum!=num1+num2) { out.println(0); return; } } sum = num1+num2; } } if(sum!=Integer.MIN_VALUE) { if(isCons1(a,b,sum,k)) { out.println(1); return; } else { out.println(0); return; } } int l = -1; int r = (int)(k)+1; while (r-l>1) { int mid = (l+r)/2; if(isCons(a,b,mid,k)) { r=mid; } else { l=mid; } } out.println(k-r+1); }
»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

I have a solution for F without DSU or prefix sums, just three variables: https://codeforces.me/contest/2106/submission/317081638 . Idea is the same as in editorial, and also all the possible transitions (00, 01, 10, 11) change connected component sizes in a very particular way. Hope it will stand against hacks

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +12 Проголосовать: не нравится

Here is an easier solution to F : 317055960

The approach is that, at any position, there is at max one lower half of ongoing 0s and one upper half of ongoing 0s, so I just keep on updating the number of 0s in the lower and upper half for each index, and the answer is max value of the upper/lower half accross all indexes.

Really liked the problem :)

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

For problem C, I found it easier to think of it like this:

Spoiler

C++ code: 316991209

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +4 Проголосовать: не нравится

W problemset, had so much fun!

»
18 месяцев назад, скрыть # |
← Rev. 3  
Проголосовать: нравится +18 Проголосовать: не нравится

Alternate algorithm for G2 to find the root: Find the Heavy light decomposition of the tree. Arbitrarily root the tree at 1. Lets say you know that the actual root is in the subtree of x. First, binary search on the heavy path that contains node x, to find the last node y on this path which is an ancestor of the actual root. Then, binary search on the child subtrees of y which aren't its heavy subtree, to find the child subtree which contains the actual root.

The number of times this process will be repeated is O(log n), as the size of the subtree is divided by at least 2 after each iteration. Therefore this takes O(log^2 n) queries.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +6 Проголосовать: не нравится

Tyler the creator reference?

»
18 месяцев назад, скрыть # |
← Rev. 2  
Проголосовать: нравится +3 Проголосовать: не нравится

We can solve G2 in $$$N + 3log(N)$$$ queries, which is about $$$N+30$$$ = 1030 queries.

  • Step 1) Find root in $$$3log(N)$$$ queries
  • Step 2) Once root is known, we can use prefix sums and again query $$$N$$$ times, to get all $$$N$$$ unknown values, in $$$N$$$ queries.

STEP 1)

  • Find centroid, select some children subtrees of this centroid such that total size is close to $$$N/2$$$. Make a Type-1 query with these selected childrens.
  • Type 2 query on centroid, (flip centroid value).
  • Again perform previous Type-1) query, if the delta change in query replies is $$$2|children|$$$, then the root is not part of selected subtrees, or else root is part of selected subtrees.
  • We can find the root of tree in $$$3log(N)$$$ queries, which can be used to compute the values of other nodes.

STEP 2)

  • Now we can make Type-1 query for individual nodes, we get the sum of costs from each node to root. We can use difference array ideas to compute actual values of each node.

Submission: 317054904

  • »
    »
    18 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    It is not always possible to find subtrees of size exactly n/2, e.g. all subtrees could have size n/3.

    It is easy to show that we can at least remove 1/4 of the vertices; if we sort the subtrees in descending order (by size) and take while the new sum is less than n/2, we take at least n/4 vertices (assume that we took less, then the next biggest subtrees has size <1/4 so we can take that).

    But this would mean that you need around 3 * 24 queries to find the root.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

There is a very clean and easy solution for G1.

  1. Let $$$d_1$$$ = Query 1 on {$$$1$$$}. $$$d_1$$$ can be one of {$$$1,-1,2,-2,0$$$}.
  2. If $$$d_1$$$ is $$$±1$$$, then $$$1$$$ is the root. In this case, we can easily find the answer.
  3. Else, if $$$1$$$ is not the root. Then let $$$r$$$ be the root. Then all simple paths to all nodes (except $$$r$$$ and $$$1$$$) passes through 1. If $$$d_1$$$ is not $$$0$$$, then toggling $$$1$$$, makes $$$d_1=0$$$ . Now, we can ask query 1 on all nodes from $$$2...N$$$. Let $$$d_i=$$$ Query 1 on {$$$i$$$}. Then, $$$ \text{ans}[i] = d_i \text{ for } i=2...N $$$. If $$$d_1=0$$$, then toggling $$$1$$$ and then querying on {$$$1$$$}, gives the value of node 1. Else if $$$d_1 \lt 0$$$, then value of node 1 is $$$-1$$$, otherwise it is $$$1$$$.

Sorry, for bad English.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

I think problem F is so nice,I used extended DSU to deal with it. I enjoyed it so much.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Hi! Does anyone have a dp solution of problem D?

:D

  • »
    »
    18 месяцев назад, скрыть # ^ |
    ← Rev. 2  
    Проголосовать: нравится +1 Проголосовать: не нравится

    for fixed k, we can use dp to check whether we can pick m flowers in O(n) time.

    Let dp[i][0]: amount of flowers we picked without using magic when walked to i-th flower

    dp[i][1]: amount of flowers we picked that we have used magic when walked to i-th flower

    Then we have:

    dp[i][j] = dp[i-1][j] + 1 IF b[dp[i-1][j]] <= a[i]

    dp[i][j] = dp[i-1][j] IF b[dp[i-1][j]] > a[i]

    dp[i][1] = max(dp[i][1],dp[i][0]+1) IF b[dp[i][0]]<=k (that is if we use magic)

    Note that we can use magic at n+1 positions so the last trainsmition needed for all i from 0 to n.

    And then we do binary-search on k to solve the problem. Total time complexity is O(nlogA)

    You can simplify dp process by only record dp[i][0] and dp[i][1] values when i iter from 1 to n. Here's my code for this approach 317052110

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

i love this contest

»
18 месяцев назад, скрыть # |
← Rev. 2  
Проголосовать: нравится +3 Проголосовать: не нравится

G1&G2 are great problems! Solution of G2 can be figured out much more easily with the inspiration of G1.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Why hasn't the implementation code uploaded yet?

»
18 месяцев назад, скрыть # |
← Rev. 2  
Проголосовать: нравится +1 Проголосовать: не нравится

I have a simpler solution for G1.

At the beginning, first query $$$\texttt{1 1 1}$$$. If the obtained answer $$$\bmod 2 = 0$$$, then $$$1$$$ is not a root, otherwise it is.

If $$$1$$$ is not a root, we first set $$$v_1 + v_{root} = 0$$$. We can complete this by at most one operation $$$\texttt{2 1}$$$.

Then for each $$$2\leq i\leq n$$$, we query $$$\texttt{1 1 i}$$$. Obviously, the obtained answer is $$$r_i$$$.

Then we can finish it in $$$O(n)$$$ times.

If $$$1$$$ is a root, for each $$$2\leq i\leq n$$$, we query $$$\texttt{1 1 i}$$$. Obviously, the obtained answer is $$$r_i + r_1$$$. Since we know $$$r_1$$$, it is very easy to obtain $$$r_i$$$.

submission:https://codeforces.me/contest/2106/submission/317057915.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

Great contest, though I didn't participate in

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

It is really good contest.The question is standard quality.Thank you contest organizers.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится +3 Проголосовать: не нравится

Thankyou for the great contest! Was able to get three problems in Div 3 after a long time. Had taken a hiatus. Would you say the first three were a bit easier than usual?

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

An amazing solution of Problem F with DP !

#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N = 200010, INF = 0x3f3f3f3f, mod = 998244353;
int dp[N][2];

void solve() {
	int n; cin >> n;
	string s; cin >> s;
	for(int i=1;i<=n;i++) dp[i][0] = dp[i][1] = 0;
	for(int i=1;i<=n;i++) {
		if(s[i-1] == '0') {
			dp[i][0] = dp[i-1][0] + i-1;
			dp[i][1] = dp[i-1][1] + n-i;
		} else if(s[i-1] == '1') {
			dp[i][0] = dp[i-1][1] + 1;
		}
	}
	int res = 0;
	for(int i=1;i<=n;i++) res = max({res,dp[i][0],dp[i][1]});
	cout << res << '\n';
}

signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int _; cin >> _;
	while(_--) solve();
    return 0;
}
  • »
    »
    18 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    Wow!this slution is very amazing!

  • »
    »
    18 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    bro can you please explain this solution?

    • »
      »
      »
      18 месяцев назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится

      Start by constructing the matrix

      for example

      • 1 0 0 1 0

      matrix

      • 0 0 0 1 0
      • 1 1 0 1 0
      • 1 0 1 1 0
      • 1 0 0 0 0
      • 1 0 0 1 1

      pay attention to the columns. you will find :
      0 : the column is divided into two parts by 1
      1 : the column is divided into two parts by 0

      We use $$$dp[i][0]$$$ to represent the number of zeros in the top half of column i and $$$dp[i][1]$$$ to represent the number of zeros in the bottom half of column i

      0 will contribute $$$i - 1$$$ and $$$n - i$$$ to the upper and lower parts of the previous column, respectively.

      1 would contribute $$$1$$$ to the bottom half of the previous column. Since i is traversed backward and forward, this contribution is considered to be added to the top half for columns i+1

      So we get the transfer equation

      0:

      $$$dp[i][0] = dp[i-1][0] + i - 1$$$
      $$$dp[i][1] = dp[i-1][1] + n - i$$$

      1:

      $$$dp[i][0] = dp[i-1][1] + 1$$$
      $$$dp[i][1] = 0$$$

      If you are still confused, try to exemplify a simple example yourself and follow the process to get the answer, which can help you understand.

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

what is wrong in this submission for E?317165447

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Anybody can tell me where this solution for E fails? I know it is overcomplicating the problem a little bit, but I can see eventually no difference between it and the editorial

Solution: 317115381

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Can anyone tell me where this solution is failing for C: https://codeforces.me/contest/2106/submission/317190195. I have been stuck finding the testcase in the whole contest. Even still i can't find any difference between the correct code and mine. Thanks in advance

  • »
    »
    18 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    Try it on the following input:

    1
    4 99
    0 0 0 0
    0 1 0 0
    
  • »
    »
    18 месяцев назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    This line is problematic:

    if(sum != - 1) yes = ((a[i] + b[i]) != sum? 0: 1);
    

    Say at first you get a sum of $$$x$$$, then you get a sum of $$$y \neq x$$$ , and finally another sum of $$$y$$$. In this case, the final value for the variable yes will be true, and not false.

    This might explain why the testcase you are failing is expecting you to output 0, whereas your answer is 1

»
18 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

SpyrosAliv problem E is one of the best binary search problems I have ever met

»
17 месяцев назад, скрыть # |
← Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

For E, I solved thinking that my swaps are limited to $$$[L,R]$$$ as well, which ended up in me learning merge sort tree! here's the code if someone is interested, TC: $$$ O((n+Q) \log^2 N)$$$

C++ code

just put L,R in MST query and voila we can solve for restricted swaps as well!