TheEvilBird's blog

By TheEvilBird, 3 months ago, translation, In English
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
Tutorial is loading...
  • Vote: I like it
  • +104
  • Vote: I do not like it

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been translated by TheEvilBird (original revision, translated revision, compare)

»
3 months ago, hide # |
 
Vote: I like it +36 Vote: I do not like it

Great contest, fast editorial

C was harder than D for me

  • »
    »
    3 months ago, hide # ^ |
     
    Vote: I like it +1 Vote: I do not like it

    for me B was harder than c and d.

  • »
    »
    7 weeks ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    I agree. D's approach and implementation are very natural, requiring only a bit of math and a greedy strategy. The complexity is also easier to estimate than C. Regarding C, I thought that N*D*26 would be quite large for N = 50000. I had to think of a way to optimize it down to O(N*max(D,K,26))

»
3 months ago, hide # |
Rev. 2  
Vote: I like it 0 Vote: I do not like it

A question about D: My solution is sorting all the "1"s by the Manhattan Distance to the bottom left corner, and add them one by one. Why it is true?

  • »
    »
    3 months ago, hide # ^ |
     
    Vote: I like it +3 Vote: I do not like it

    This is an interesting idea. My intuitive proof of this idea is as follows: Suppose we have a table with the following condition:

    1 0 1 1 0

    0 1 0 1 1

    1 0 1 0 0

    0 1 0 1 0

    0 0 0 0 1

    We want to put $$$\frac{cnt1}{2}$$$ 1's into one of the tables (let's say the bottom left one, as you've suggested), and all the rest into the opposite one. Let's try to greedily assemble the bottom left table. It should contain $$$\frac{cnt1}{2}$$$ ones. Let's try to take them one by one, taking EXACTLY ONE '1' at a time and not taking anything extra.

    Note that if we take the first unit other than the one closest to the lower left edge (let's say we take {i=0, j=3} as the first unit), then it's clear that we'll capture a very large region, which will most likely contain 1's with a shorter Manhattan distance to the lower left corner.

    If we take 1's one by one, we guarantee that we'll ALWAYS take EXACTLY one '1'. (Consider the operation not as a matrix cut, but as a union of the current submatrix with the submatrix of the current element (see photo)). We can always take a submatrix such that the '1' is its upper right corner. This means there won't be any extra 1's inside.

    (I claim that a similar approach to your idea can be used for the upper right corner.)

»
3 months ago, hide # |
 
Vote: I like it +7 Vote: I do not like it

Why is it still not possible to upsolve problems?

  • »
    »
    3 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it 0 Vote: I do not like it

    i think it's because the olympiad on which this round is based hasn't yet had offline testing part for some problems (or they just forgot abt it)

»
3 months ago, hide # |
 
Vote: I like it +12 Vote: I do not like it

for whose who ask why the optimal answer for problem $$$D$$$ is $$$\frac{k} {2}$$$ :

first the total answer if we make each part has $$$\frac{k} {2}$$$ ones is $$$\frac{k^{2}} {4}$$$.

now lets assume that in the first part we have $$$\frac{k} {2} + m$$$ for some positive $$$m$$$, then the answer will be:

$$$(\frac{k} {2} + m) * (k - \frac{k} {2} - m) = (\frac{k + 2 m} {2}) * (\frac{k - 2 m} {2})$$$ = $$$\frac{k^{2} - 4m^{2}} {4}$$$ = $$$\frac{k^{2}} {4} - m^{2}$$$ $$$ \lt $$$ $$$\frac{k^{2}} {4}$$$

similarly if we assume the answer is $$$\frac{k} {2} - m$$$ then the answer will be the same which is strictly less than $$$\frac{k^{2}} {4}$$$.

»
3 months ago, hide # |
 
Vote: I like it +6 Vote: I do not like it

I solved E a bit differently, here was my thought process:

There's exactly 1 cell on every diagonal we visit for every path from $$$(1,1)$$$ to $$$(n,m)$$$. That is, for every $$$c$$$ from 1 to $$$n+m$$$, there is exactly one $$$(x,y)$$$ on the path where $$$x+y = c$$$. The proof is just by noting that every step on this path increments $$$(x,y)$$$ by exactly 1.

Now let $$$dp1[i][j]$$$ be the max enjoyment from $$$(1,1)$$$ to $$$(i,j)$$$, excluding the enjoyment from the cell $$$(i,j)$$$. Let $$$dp2[i][j]$$$ be the max enjoyment from $$$(i,j)$$$ to $$$(n,m)$$$, including the enjoyment from the cell $$$(i,j)$$$. The reason why I'm defining the dp's asymmetrically about counting cell $$$(i,j)$$$ is so that $$$dp1[i][j] + dp2[i][j]$$$ is the max enjoyment going through $$$(i,j)$$$. Both these dps are standard, can be calculated in $$$O(mn)$$$ time.

Now for the key idea: what's the max enjoyment if you don't go through $$$(i,j)$$$? Since you visit exactly 1 cell in each diagonal, you can just find the max enjoyment by going through every cell on the "$$$i+j$$$" diagonal except $$$(i,j)$$$. This gave me the idea to just store $$$dp1[i][j] + dp2[i][j]$$$ separately, now if you want to find the max enjoyment by negating $$$i,j$$$, modify the value of $$$dp1[i][j] + dp2[i][j]$$$ in the "$$$i+j$$$" set by decrementing it by $$$2*a[i][j]$$$, and find the max value of that set. Do this for every element of the grid and you have your answer.

Yes this answer has an extra log factor because of sets but I think you can remove that too by instead of maintaining sets, storing the max and second max value alone for every diagonal.

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

For D, I Really thought of using DP

Realising I was so wrong But ig mind literally burned out after 1.5 hrs giving a lot of time to solve C

»
3 months ago, hide # |
Rev. 2  
Vote: I like it 0 Vote: I do not like it

.

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

You can solve E in a really scuffed way:

Spoiler
»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Can anyone help me why my O(2*k*n*sqrt(n)) gives TLE, My solution is exactly same as what was discussed in first part

Solution
  • »
    »
    3 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it 0 Vote: I do not like it

    I think the freq vector you are creating is the reason, the creation of vectors is not constant so there is an additional factor of 26*fact during every iteration

  • »
    »
    3 months ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    You can preprocess how many of each character there are in each column outside the loop.

    • »
      »
      »
      3 months ago, hide # ^ |
       
      Vote: I like it 0 Vote: I do not like it

      got the bug, thanks guys, I have always assumed vector creation takes O(1) just like arrays but rather it's O(size). Actually I was creating freq vector inside second nested loop. That makes time complexity as O(2*n*sum(factors)*sqrt(n))

»
3 months ago, hide # |
 
Vote: I like it +6 Vote: I do not like it

in C, rather than storing a frq array for each index, store a bitmask of 26bits of which letters are possible for that index, then if you want to see if there's some character which is possible for a group of indices, then their AND should be non-zero, indicating there's at least 1 set-bit common in all, and then use __builtin_ctzll(x) to get your required character for this group. This could be useful if constraints on n were a bit tighter like 2e5, by redicing TC from O(26n√n) to O(n√n)

»
3 months ago, hide # |
 
Vote: I like it -13 Vote: I do not like it
#include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
using namespace std;

const ll mod=1e9+7;

void solve(){
    ll n, m;
    cin >> n >> m;
    vector<bool> v(n * m); 
    ll ones = 0;

    for(ll i = 0; i < n; i++){
        for(ll j = 0; j < m; j++){
            int x;
            cin >> x;
            
            v[i * m + j] = x; 
            ones += x;
        }
    }

    ll limit = ones / 2;
    ll i, j, stat = 1;
    
    for(i = 0; i < n; i++){
        for(j = m - 1; j >= 0; j--){
            
            if(v[i * m + j] == 1) limit--;
            
            if(limit == 0){
                stat = 0;
                break;
            }
        }
        if(stat == 0) break;
    }

    ll k = 0;
    string s;

    
    if(j == 0){
        k = i + 1;
        while(k--) s += 'D';
        k = m;
        while(k--) s += 'R';
        k = n - i - 1;
        while(k--) s += 'D';
    } else {
        k = i;
        while(k--) s += 'D';
        k = j;
        while(k--) s += 'R';
        s += 'D';
        k = m - j;
        while(k--) s += 'R';
        k = n - i - 1;
        while(k--) s += 'D';
    }

    cout << (ones / 2) * ((ones + 1) / 2) << endl;
    cout << s << endl;
}

int main(){
    
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    ll t = 1;
    cin >> t;

    while(t--){
        solve();
    }
}

Help me! Memory limit exceeded, have seen memory exceed first time

  • »
    »
    3 months ago, hide # ^ |
     
    Vote: I like it +6 Vote: I do not like it

    Hey a little advice. When asking questions please put your code inside code blocks as many people find it kinda annoying to see the whole code pasted as such. Have a nice day!!!`

»
3 months ago, hide # |
Rev. 5  
Vote: I like it 0 Vote: I do not like it

SPOILER , CODE PRESENT

2194D — Table Cut :

CODE

I am not able to figure out the issue here , my break_at_y ranges from [0,y] , 0 means , I dont move right at the start ,and n means i move to complete right. And my break_at_x ranges from [0,x-1] My break_at_y will try to break just before the count of prefix_y_1 becomes more than sum/2.I am taking care of some columns not having any 1. My break at x ranges from 0 to x-1 , because I try to decrement x only in case I required more 1 , if the break_y didnt get enough 1's , if not , I go till end of x , so I always need atleast 1 row here.

Wanted to discuss what I might be doing wrong.

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Why does my O(nm) solution 362095542 TLE at test case 49?

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

can someone explain how they approced B?

  • »
    »
    3 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it 0 Vote: I do not like it

    Imagine a new bank which doesn't have any money and you transfer the money from all other banks to this bank and for each bank the money you are able to transfer is equal to $$$\left\lfloor \frac{A_i}{x} \right\rfloor \cdot y$$$. You can calculate the sum over all banks. Now you just let each bank one-by-one as this new bank (now you don't have to transfer money from the current bank) and calculate the maximum money collected.

    • »
      »
      »
      3 months ago, hide # ^ |
       
      Vote: I like it 0 Vote: I do not like it

      But we can pair two banks (say Ai and Aj) such that money transferred from Ai to Aj will make amount in Aj multiple of x, which will help in removing the residue from Aj and maximize the money if transferred from Aj. Wouldnt this approach be more optimal?

      • »
        »
        »
        »
        3 months ago, hide # ^ |
         
        Vote: I like it 0 Vote: I do not like it

        Yeah I tried to say the same thing. But I was trying to explain how I approached the solution instead of the solution itself as asked above.

      • »
        »
        »
        »
        3 months ago, hide # ^ |
         
        Vote: I like it +1 Vote: I do not like it

        As far as I understand it, the money lost in the additional transfers from Ai to Aj, and then Aj to the final bank, is equal to what would have been left as residue in both Ai and Aj if they went straight to the final bank.

      • »
        »
        »
        »
        3 months ago, hide # ^ |
        Rev. 2  
        Vote: I like it 0 Vote: I do not like it

        thats what confused me for SO LONG

        but i think ive finally got it-

        on one hand: intermediate transfer to an account with residual amount<x will help in utilising that amount.

        on the other: the additional number of transfers in doing so will lead to more wastage.

        trying to justify case 1:

        the best case scenario for this is when x==y so that there is x-y=0 loss in each transfer, even in doing so bank a has amount k>=x, number of transfer to bank b=k/x; suppose,k/x=N

        bank b has amount f<x, total amount after intermediate transfer=k+f
        number of transfers to final bank=(k+f)/x==N,as f<x

        thus no effect on final amount, and if x-y>0, its even worse than direct transfers.

        hope this helps!!

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

In F, shouldn't dp[v][x] be added to dp[v][xor_subtree[v]] instead?

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Good round!

»
3 months ago, hide # |
 
Vote: I like it +4 Vote: I do not like it

I had a slightly different solution for problem E (2194E - The Turtle Strikes Back), that is perhaps slightly simpler, though it has the same complexity.

Consider the cells that lie on an antidiagonal of the grid, for example:

...x
..x.
.x..

Since Michaelangelo's path can only go right or down, each path from top-left to bottom-right must pass through exactly one of the cells on this diagonal (and that is true for each parallel line). We can calculate the value of the optimal path going through each of these cells using the dpS and dpT memos as described in the editorial.

Now, the key point is that we only need to consider the best 2 cells on the diagonal. If the cell through which the maximal path runs has a positive value, then Raphael can invert it to reduce the value of the path going through it. It might still be the best possible path, or maybe Michelangelo will have to switch to the path with the second-best value, but he never has to switch to any of the other paths.

So we can process each diagonal one by one, covering all possible cells, for an $$$\mathcal{O}(nm)$$$ solution.

Slightly messy solution I submitted during the contest: 361983731

»
3 months ago, hide # |
Rev. 2  
Vote: I like it -7 Vote: I do not like it

why d cannot have multiple answers?? i have taken a iterator and iterated till count of 1 divided by 2 and if there is 1 in the 1st block greater than count1/2 (which will divide whole array in two parts)then i will take a iterator such that it elements 1 till count1/2== no of 1s in first block, and then i will iterate till right and down till till i have reached end of block 1 and then totally down and then totally right. where i am wrong? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //This is the code

include <bits/stdc++.h>

using namespace std; using ll = long long; void solve(){ int n,m; cin>>n>>m; int arr[n][m]; string s; int count1=0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>arr[i][j]; if(arr[i][j]==1) count1++; } } int tempc=0; int checkc=0; for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(arr[j][i]==1) tempc++; checkc=i; } if(tempc>=count1/2) break; } int extra=tempc-count1/2; int temp=extra; int checki=0; int checkj=0; if(extra>0){ for(int i=0;i<n;i++){ for(int j=checkc;j>=0;j--){

if(arr[i][j]==1) extra--;
            checki=i;
            checkj=j;
            if(extra==0) break;
        }
        if(extra==0) break;
    }
    cout<<checki<<" "<<checkj<<endl;
    int j=0;
    while(j<checkj){ s.push_back('R'); j++;}
    int i=0;
    while(i<=checki){ s.push_back('D');i++;}
    int k=j;
    while(k<=checkj){ s.push_back('R');k++;}
    while(i<n){ s.push_back('D'); i++;}
    while(k<m){s.push_back('R'); k++;}
}
else{
    for(int j=0;j<=checkc;j++) s.push_back('R');
    for(int i=0;i<n;i++) s.push_back('D');
    for(int k=checkc+1;k<m;k++) s.push_back('R');
}
int ans=0;
if(count1%2==0) ans=(count1/2)*(count1/2);
else ans=(count1/2+1)*(count1/2);
cout<<ans<<"\n"<<s<<"\n";

} int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin>>t; while(t--) solve(); return 0; } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ can anyone please help?

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Thank you for the great contest and editorial. Nevertheless I found problem F1 a bit difficult for me, even with the help of the editorial. Can anyone share more details on the solution and thought process and also can share similar problem to practise?

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

I have a question about problem E.

I have a solution where there is 3d dp n*m*2. I will call this dp 2-layered:

  • layer-zero, where each cell (i, j) presents the best result when none of cell was turned into bad one;
  • layer-one, where one of cells in path to cell (i, j) was turned into bad one and we went through it.

The logic I used:

  • we can get into dp[i][j][0] only from it's left or upper cells on the same layer;
  • to get into dp[i][j][1] we have two oprions:
  1. current cell (i, j) is turned into bad, so we can get there only from layer-zero: dp[i][j][1] = max(dp[i - 1][j][0], dp[i][j - 1][0]) - a[i][j];
  2. some cell before (i, j) was turned into bad, so we can get there only from layer-one: dp[i][j][1] = max(dp[i - 1][j][1], dp[i][j - 1][1]) + a[i][j];
  • as the second turtle decides which cell to turn into a bad one, so we need to pick min of these two options (as I think)

Summing up, have this moves:

dp[i][j][0] = max(dp[i - 1][j][0], dp[i][j - 1][0]) + a[i][j];

dp[i][j][1] = max(min(dp[i - 1][j][0], dp[i][j - 1][0]) - a[i][j]), min(dp[i - 1][j][1], dp[i][j - 1][1] + a[i][j]));

In most, that is all my solution.

But it doesn't work on test 1. And I still cannot undestand why.

Can anybody explain what is wrong with this approach?

Thanks in advance

  • »
    »
    3 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it 0 Vote: I do not like it

    It forces Michelangelo to choose a path that passes through the cell Raphael selected, which is not always the case. Suppose there exist two independent optimal paths, p1 and p2, with sums s1 and s2, and maximum cell values a1 and a2, respectively, before Raphael makes his move. Then, if Raphael chooses a1, Michelangelo can use p2, or vice versa. Therefore, it misses option 2 in the editorial: Choose a path from (1, 1) to (n, m) that does not pass through cell (i, j).

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

I think D is harder than E.

»
3 months ago, hide # |
 
Vote: I like it +8 Vote: I do not like it

Here is an approach to F1 that does not use XOR basis.

Since XOR is its own inverse, removing a subgraph that has an XOR sum of $$$b_j$$$ from a subtree $$$u$$$ is equivalent to applying an XOR of $$$b_j$$$ on $$$u$$$. Thus, we just need to maintain the parity of the number of times we have cut a subgraph with XOR sum $$$b_j$$$.

Our dp state is $$$dp[u][mask]$$$, where $$$u$$$ is the subtree and $$$mask$$$ stores the parity of the number of times $$$b_j$$$ has been cut.

Our transitions can be done with an XOR convolution, so our solution runs in $$$O(n*4^k)$$$.

Submission: 362338987

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Does anyone know how we can generate tests for problem F2 ?

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Neat and Clean explanations especially in C and D. Thank you!

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

though I didn't join this contest , I still think it is a great round !!!

»
3 months ago, hide # |
Rev. 2  
Vote: I like it 0 Vote: I do not like it

In question E, shouldn't it be at most 1 instead of exactly 1?

Because he can choose not to select any pizza to apply sauce?

»
3 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

F2 is so hard, i haven't learnt fft yet, let alone fwt:)). How can i get documents about fft and fwt , i want to learn these algorithms to solve F2:)

»
2 months ago, hide # |
Rev. 5  
Vote: I like it 0 Vote: I do not like it

i can't passed F2 because of TLE on test 6,where can i imporve in this code. code

Code
»
2 months ago, hide # |
Rev. 5  
Vote: I like it 0 Vote: I do not like it

Can Someone pls explain what is wrong in this code for Problem E 368187983

»
7 weeks ago, hide # |
Rev. 2  
Vote: I like it +13 Vote: I do not like it

Further explaination for the part "the second recomputation step, where we wanted to compute the value $$$dp[v][x]$$$ at certain points $$$x$$$ and add it to $$$dp[v][0]$$$ " in F2:

  • let $$$a$$$ be $$$dp[v]$$$ and $$$f$$$ be $$$hadamard(a)$$$ in the tutorial, we do not maintain $$$a$$$ directly but maintain $$$f$$$ to reflected $$$a$$$.

  • And by definition:

    • [I.] $$$f_i=\sum_j (a_j \cdot (-1)^{popcount(i\ AND\ j)})$$$
    • [II.] (by FWT) $$$a_j=\frac{1}{B} \cdot \sum_i (f_i \cdot (-1)^{popcount(i\ AND\ j)})$$$

We want to modify $$$f$$$ to reflected the operation:

  • $$$a_{tar} \leftarrow a_{tar}+dv$$$
  • $$$dv=\sum_{d} a_{tar \oplus d}$$$
  • »
    »
    7 weeks ago, hide # ^ |
     
    Vote: I like it +5 Vote: I do not like it

    (Part A:)Try calculate $$$dv$$$ by $$$f$$$ :

    $$$a_{tar \oplus d}=\frac{1}{B} \cdot \sum_i (f_i \cdot (-1)^{popcount(i\ AND\ (tar \oplus d))})$$$ (by definition)

    • $$$popcount(i\ AND\ (tar \oplus d)) \equiv popcount(i\ AND\ tar) + popcount(i\ AND\ d) (\bmod 2)$$$ $$$\rightarrow (-1)^{popcount(i\ AND\ (tar \oplus d))} = (-1)^{popcount(i\ AND\ tar)} \cdot (-1)^{popcount(i\ AND\ d)}$$$

    $$$\rightarrow a_{tar \oplus d}=\frac{1}{B} \cdot \sum_i (f_i \cdot (-1)^{popcount(i\ AND\ tar)} \cdot (-1)^{popcount(i\ AND\ d)})$$$

    $$$\rightarrow dv=\sum_{d} \frac{1}{B} \cdot \sum_i (f_i \cdot (-1)^{popcount(i\ AND\ tar)} \cdot (-1)^{popcount(i\ AND\ d)})\\ \ \ \ \ \ \ \ \ \ \ =\frac{1}{B} \sum_i (f_i \cdot (-1)^{popcount(i\ AND\ tar)} \cdot \sum_{d}(-1)^{popcount(i\ AND\ d)})$$$

    Let $$$w_i=\sum_{d}(-1)^{popcount(i\ AND\ d)}$$$ , pre-calculate it for each $$$i$$$ , then each $$$A_i=f_i \cdot (-1)^{popcount(i\ AND\ tar)} \cdot w_i$$$ can be calculated in $$$O(1)$$$, $$$dv=\frac{1}{B} \sum_i A_i$$$ can be calculated in $$$O(2^k)$$$.

  • »
    »
    7 weeks ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    (Part B:)Update $$$a_{tar}$$$ :

    Refering to [I.], just let $$$f_i \leftarrow f_i+dv \cdot (-1)^{popcount(i\ AND\ tar)}$$$ for each $$$i$$$ .

    Thus we can perform the operation (the second step) in $$$O(2^k)$$$.

    code:https://mirror.codeforces.com/contest/2194/submission/369572795

  • »
    »
    7 weeks ago, hide # ^ |
     
    Vote: I like it 0 Vote: I do not like it

    Long segments of Markdown formulas are misidentified by Codeforces as source code and required to being wrapped with "markup syntax", which breaks the formatting. So I split the full text into several paragraphs. :(