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

Автор chokudai, история, 4 года назад, По-английски

We will hold AtCoder Beginner Contest 179.

The point values will be 100-200-300-400-500-600.

We are looking forward to your participation!

  • Проголосовать: нравится
  • +79
  • Проголосовать: не нравится

»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

"We are looking forward to your participation!"

We are looking for quick editorials.

P.S. I love ABC's.

»
4 года назад, # |
Rev. 2   Проголосовать: нравится +6 Проголосовать: не нравится

What are the ALC contests of Atcoder?

Edit: It's is described in this blog

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

»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I tried a DP solution for D. Somehow getting TLE in 6 TCs. I tried to optimize it as much as I could. Am I missing something?

Link to Submission

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

    post qns only after contest is over.

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится

    i used fenwick tree to optimize it, note that k <= 10, your solution fails because ranges can be very big, so your solution is n^2

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

      But the sum of ranges won't be more than O(n) I suppose. Because the segments are nonintersecting.

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

        Yes, the sum of ranges is $$$O(n)$$$, but you also have $$$O(n)$$$ states and for each, you iterate through all of them. In total it is $$$O(n^2)$$$.

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

    you can try it in O(n*k). Refer to below link for reference.

    https://www.geeksforgeeks.org/constant-time-range-add-operation-array/

    My Submission

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

    your code runs in O(K*N) where K is the number of possible jumps, theoretically in worst case it would reach O(n^2) time complexity which could defenitely get TLE. In this problem i used dynamic programming with fenwick tree, you can look at my code here

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

    For d, you have to combine the dp you are talking about, with the range covering problem (it is easier than segment tree I leave you this video in which that guy explains that problem https://youtu.be/Zze-O2oxoEo?t=219 ) and then you just have to be careful about modulo operations (you might be doing them with negatives)

    I hope this was useful

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

      Thanks for this. I checked out the video. Isn't what he is talking about, called the Fenwick tree?

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

        No, Fenwick tree is a little more complex than that, it is about having sum until last significant bit and when doing a query going up from last significant bit to most significant bit (with a complexity of logn) and when updating is almost the same, but instead of getting an answer, updating; that is why it is also called Binary Indexed Tree

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

    My code is similar with yours and I wonder how to optimize it too. [submission:#17148205]

»
4 года назад, # |
  Проголосовать: нравится +27 Проголосовать: не нравится

First time in ABC I was able to solve all problems. Here are short explenations.

F
E
D
C

Funfact, I had no WA, all AC on first submission.

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +7 Проголосовать: не нравится

    For d instead of segment tree + dp you can use prefix array + dp.

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

      please share your code

      • »
        »
        »
        »
        4 года назад, # ^ |
          Проголосовать: нравится +3 Проголосовать: не нравится
        • »
          »
          »
          »
          »
          4 года назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          plz give a brief explanation also. thnx

          • »
            »
            »
            »
            »
            »
            4 года назад, # ^ |
            Rev. 5   Проголосовать: нравится +3 Проголосовать: не нравится
            Basic
            Solution
  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +6 Проголосовать: не нравится

    You don't really need a segment tree for D
    I just used prefix sums

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

    D and E should have been swapped ,I didn't even attempt E after continuous TLE's in D .

  • »
    »
    4 года назад, # ^ |
    Rev. 2   Проголосовать: нравится +24 Проголосовать: не нравится

    You don't need segment tree for F either.

    Code
    • »
      »
      »
      4 года назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      can you explain your approach for F

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

        I'm more than a month late, you may have got the answer till now, but here is what I think the approach is:

        Here two sets are used to maintain position of lines of white stones. There are two kinds of lines length wise :

        1. Partial lines(going from one end and ending halfway)

        2. Complete lines (going from one end to other end)

        There are two kinds of lines possible orientation wise :

        a) Horizontal Line - Can be stored as $$$y$$$ co-ordinate it starts on and $$$x$$$ co-ordinate it ends on.

        b) Vertical Line - Can be stored as $$$x$$$ co-ordinate it starts on and $$$y$$$ co-ordinate it ends on.

        Now what exactly those two sets do, set[0] stores position for horizontal lines, and set[1] stores position of vertical lines.

        Formally a pair stored in respective sets looks like:

        • s[0]= (Ending abscissa, originating ordinate)
        • s[1]=(Ending ordinate, originating abscissa)

        Note that at the start we only have two complete lines, one horizontal and one vertical that's why a pair $$$(n,n)$$$ is stored in both the sets.

        • Query 1 We search for nearest horizontal line we can find that ends after $$$x$$$, and thus add remove black stones in that interval from the answer accordingly and now one vertical line is created in the process that starts at $$$x$$$ and ends just before the horizontal line we found.

        • Query 2 Search for nearest vertical line, remove black stones in that range from the answer and add a horizontal line in the corresponding set.

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

    F: you can use std::map for the same query (lower_bound to find closest) Submission

    D: you can use only partial sums of your dp and fill dp[i] with sum of previous values Submission

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

    I also thought of using segtree with lazy prop on F, but I had no segment tree template with lazy propagation :P and I had only 35mins left. So I quit. Missed my chance of solving all problems in ABC for the first time.

    I'm taking your template now XD.

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

      I also got idea of two lazy segment tree immediately but I haven't implemented even a basic lazy segment tree before so I gave up. Now I am seeing there are other solutions too

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

      I had to fix a bug in that template in function rangeInc(). Not sure if everything works fine.

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

        Oh,thanks for informing. I'll test it properly after customizing it for myself. :)

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

          In AtCoders ACL library there is a segment tree, too. I would like to switch to that one, but need time to get used to it.

          ACL lib

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

      Question: I thought that we should need to be able to get the historically minimum of some certain index? Won't that be more than just a plain old segtree?

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

    I got tle in this, could you plz tell me why?

    int ans = 0;
    for(int i = 1 ; i <n; i++){
    	int x = n-i;
    	for(int j = 1; j*j<=x; j++){
    		if(x%j == 0){
    			ans++;
    		if(x/j != j){
    			ans++;
    		}
    		}
    	}
    }
    // ans += ans;
    cout << ans ;
    
    • »
      »
      »
      4 года назад, # ^ |
      Rev. 5   Проголосовать: нравится 0 Проголосовать: не нравится

      You have asymptotic of $$$O(n \sqrt{n})$$$ which is too big. You can enumerate only the smallest number of $$$A, B$$$ which would be $$$\sqrt{n}$$$ and calculate how many multipliers bigger than your number you can have such that $$$A \times B$$$ is smaller than $$$N$$$.

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

      n is 1e6, so the inner loop runs up to 1e3 times... that are aprox 5e8 iterations.

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +3 Проголосовать: не нравится

    Me too for the first time solved set in any contest lol

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

    Can you please further explain how did segment tree help with this problem? I know segment tree but I cannot utilize it to solve this problem.

    • »
      »
      »
      4 года назад, # ^ |
        Проголосовать: нравится +3 Проголосовать: не нравится

      I assume problem D.

      If we would do standard knapsack we would need to loop over all the values in the K ranges, which is O(n).

      With the segment tree we are able to do these updates in O(log n).

      Note that the solution with the partial sums do these updates in virtually O(1). see here

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

    correct me if I am wrong, the time complexity of your D solution is N*k*log(n) and not N*log(n) which the editorial says is the optimum

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

      Yes, you are right. Because of this my submission needs 800+ms instead of possible 10ms.

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

    In problem E , How can I know that the series will repeat itself ?

    • »
      »
      »
      22 месяца назад, # ^ |
      Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

      It is the pidgeonhole principle. Since all values of the series are in range 0..M-1, there is a repitition after at most M values.

»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

How to solve problem D?

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Спойлер
  • »
    »
    4 года назад, # ^ |
    Rev. 2   Проголосовать: нравится +7 Проголосовать: не нравится

    I solved it without segment tree

    I used difference array. Time complexity of $$$O(N*K)$$$

    basically let dp[i] be no of ways to each i.

    Then you increment, $$$i$$$+$$$L_j$$$ to $$$i$$$+$$$R_j$$$ with dp[i], increment using difference array method, and keep summing as you move toward right.

    The answer would be dp[n]

    Submission

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

    I solved it maintaining a prefix sum array and using dp.

    dp[i] = sum of dp[j] for all j, i is reachable. As the range was contiguous it was easy to get the sum of dp[j] using prefix sum.

    My Sumbission

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

      could u plz explain more

      • »
        »
        »
        »
        4 года назад, # ^ |
        Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

        Here dp[i] is the number of ways to reach i.

        dp[i] was calculated by the sum of dp[j] for all j from where i is reachable. Assume i = 4 and i is reachable from 2 and 3. If the number of ways to reach 2 is 1 aka dp[2] = 1 and the number of ways to reach 3 is 2, dp[3] = 2 then dp[4] = dp[2] + dp[3] which is dp[4] = 3 (rule or sum)

        And for any i corresponding js were calculated from the ranges and their sum was calculated from the the prefix sum array. For any position iand a range L, R i is reachable from all valid i-R, i-L.

        Finally the answer is dp[n].

        Complexity O(N*K)

»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I got runtime error in sometest cases in prob D with segtree can somebody help me? https://atcoder.jp/contests/abc179/submissions/16889464

»
4 года назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится
void test_case() {
	int n , x;
	cin >> n >> x;
	for(int i = 0 ; i < 2*x ; i++){
		int p;
		cin >> p;
		c.insert(p);
	}
	dp[1] = 1;
	for(int i = 2 ; i <= n ; i++){
		for(auto j : c){
			if(j <= i){
				dp[i] = (dp[i]%M+dp[i-j]%M)%M;
			}
		}
	}
	cout<<dp[n]%M;
}
 

what WA in my D https://atcoder.jp/contests/abc179/submissions/16888327[my sol link](http://https://atcoder.jp/contests/abc179/submissions/16888327)

  • »
    »
    4 года назад, # ^ |
    Rev. 3   Проголосовать: нравится +3 Проголосовать: не нравится

    they want you to union the segments [Li,Ri] i mean {Li,1+Li,2+Li,3+Li,....,Ri} not only values {Li,Ri}

»
4 года назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

It`s the first time I AK abc! LOL

»
4 года назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

I tried to solve D by repeating knapsack dp approach with time complexity O(N*m).But TLE destroyed my today's contest.Can anyone help me with that?

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +1 Проголосовать: не нравится

    D can be done in O(n*k).

    Use range update operation on array, it will take O(n) for each range.

    My submission

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

      Can you elaborate this part?

      if(i+range[j].F<=n) temp[i+range[j].F]=(temp[i+range[j].F]+dp[i])%M; if(i+range[j].S+1<=n) temp[i+range[j].S+1]=(temp[i+range[j].S+1]-dp[i]+M)%M;

      • »
        »
        »
        »
        4 года назад, # ^ |
          Проголосовать: нравится +1 Проголосовать: не нравится

        Suppose you have array 1 2 3 4 5 You want to add 2 from position 2 to 4 [1 based-indexing) You can take a temp array and make temp[2]=2 and temp[5]=-2

        Now you can iterate over array and take sum+=temp[i]

        And add sum to a[i] . You can get the required array after update in O(n) this way.

»
4 года назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

Eagerly waiting for geothermal's editorial.

»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Hello in D no I used the similar pattern of dp like CSES-Coin Combinations I. but get TLE from that.Isn't it the similar pattern problem.

My solution is here

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

    Thats' so because the time complexity of your solution is O(n*n).

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

      I thought it's like Coin Combinations I problem.My bad.How can I solve it using dp ?

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

        Well, usually i solve 4-5 problems in ABC contest but today i was able to solve only the first three!

»
4 года назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

Could anyone please explain the 1 testcase this is failing on? I have tried to find a cycle and then adding to the sum the sum of that cycle and then adding the rest seperately.Submission

»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

how to solve D? someone with good explanation?

  • »
    »
    4 года назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    You can use this dp: dp[i] means how many ways do you have to go to the i-th cell.

    Let's get an array of long long dp[2n]. First we fill it with zeros. Denote the sums[2n] as prefix sums array of dp.

    1. dp[n] = 1, sums[n] = 1

    2. for each cell from n+1 to 2*n and each segment (l[j], r[j]) we calculate: dp[i] = (mod + dp[i] + sums[i - l[j]] - sums[i - r[j] - 1]) % mod

    You can understand that part as: to get how many ways I have to go to the i-th cell, I should sum the ways from all dp[the previous one, from which you can get into this].

    The value sums[i - l[j]] - sums[i - r[j] - 1] gets us sum: dp[i - r] + dp[i - r + 1] + ... + dp[i - l]

»
4 года назад, # |
Rev. 2   Проголосовать: нравится +11 Проголосовать: не нравится
»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

how do you solve c? I got TLE my solution is only O(n^2)

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

    $$$O(N^2)$$$ is too large for $$$N=10^6$$$.

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

      How can i know that it's large or not?

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

        You just put N into the time complexity expression and evaluate it. Generally speaking, $$$10^7$$$ is totally acceptable, while $$$10^8$$$ can be a bit dangerous (on some OJs it cannot pass), and $$$10^9$$$ is almost impossible to pass the time limits.

        However, sometimes we also need to consider the constant, which is omitted in the time complexity expression.

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

    can somebody please explain the logic for c.

    n = int(input())
    cnt = 0
    for i in range(1, n):
        cnt += (n - 1) // i
    print(cnt)
    
    • »
      »
      »
      4 года назад, # ^ |
      Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

      Since N is fixed, we don't need to enumerate all possible triplet of (A, B, C), we only need to enumerate (A, B) and compute C accordingly. Such method can be improved by enumerating only A and find the upperbound and lowerbound of B. All the values between lowerbound and upperbound are valid B. Note that B should be integer.

      $$$0 \lt A \cdot B = N - C \lt N \implies 0 < B < N/A$$$

      N = int(input())
      ans = 0
      for A in range(1, N):
          lb = 1
          ub = math.ceil(N / A) - 1
          ans += ub - lb + 1
      print(ans)
      
»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

I believe F can be solved using monotonic set

»
4 года назад, # |
Rev. 3   Проголосовать: нравится +5 Проголосовать: не нравится

I have written an unofficial English editorial.you can find it here.

UPD: Added editorial for problem F.

  • »
    »
    4 года назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится

    In the explanation for C : Could you please explain how the number of ways of choosing is N/A ?

    I have tried to do it on paper but couldnot come up with the intution.

    • »
      »
      »
      4 года назад, # ^ |
        Проголосовать: нравится +5 Проголосовать: не нравится

      It should be $$$\frac{N - 1}{A}$$$ fixed it now, thanks for notifying me.

      The reason for that is for every $$$A$$$ there can be $$$\frac{N}{A}$$$ numbers for be such that $$$ A \times B \le N$$$, however we should subtract $$$1$$$ because $$$C$$$ can't be equal to zero.

»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Can E be solved with Matrix exponentiation??

»
4 года назад, # |
Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

I tried to solve E,but for some unkown reason,I got two RE.

Can you help me?

Code
»
4 года назад, # |
  Проголосовать: нравится +3 Проголосовать: не нравится

Editorial D

How to solve in O(nlogn) when the transitions cannot be written as a sum of small number of segments?

  • »
    »
    4 года назад, # ^ |
    Rev. 2   Проголосовать: нравится +8 Проголосовать: не нравится

    [ignore this, too much complex]

  • »
    »
    4 года назад, # ^ |
    Rev. 2   Проголосовать: нравится +12 Проголосовать: не нравится

    let $$$J$$$ be the set of possible jump lengths, now $$$ J = \cup[l_i,r_i] $$$

    Now we can use generating function $$$ G $$$ to define that set.
    $$$G = \sum_{i=0}^N c_i x^i $$$ where $$$ c_i = 1$$$ if $$${i \in J}$$$ else $$$c_i = 0$$$.

    Now, number of ways to reach from $$$1$$$ to $$$N$$$ using exactly $$$k$$$ jumps = $$$[x^{N-1}] G^k$$$.

    As there is no restriction of jumps,so we sum it over all possible $$$k$$$.
    so, finally what we need is $$$[x^{N-1}]\sum_{k>=0} G^k = [x^{N-1}]\frac{1}{1-G}$$$

    now coefficient of $$$ x^{N-1} $$$ in the polynomial $$$\frac{1}{1-G}$$$ can be easily calculated by calculating inverse of polynomial $$$ 1 - G $$$ restricted to max degree $$$N$$$.

    Overall complexity is $$$O(N\log{}N)$$$

    For calculating inverse of polynomial you can refer Operations on polynomials and series

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

In problem E , How can I know that the series will repeat itself?

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

    Pigeon hole principle

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

      I know Pigeon hole principle but i can't understand how can we know that the series will repeat itself?

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

        There can only be $$$M$$$ different values of $$$A_i$$$. Therefore, it's inevitable that the sequence will repeat in at most $$$M$$$ iterations.

        Also this topic is 2 years old

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

        A[i] is only dependent on A[i-1]. Therefore, given the last value, there is only one and only one possible current value. It also means there can only be one and only one possible next value A[i+1].