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

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

Thank you for participating!

1926A - Vlad and the Best of Five

Idea: flamestorm

Tutorial
Solution

1926B - Vlad and Shapes

Idea: mesanu

Tutorial
Solution

1926C - Vlad and a Sum of Sum of Digits

Idea: flamestorm

Tutorial
Solution

1926D - Vlad and Division

Idea: mesanu

Tutorial
Solution

1926E - Vlad and an Odd Ordering

Idea: flamestorm

Tutorial
Solution

1926F - Vlad and Avoiding X

Idea: flamestorm

Tutorial
Solution

1926G - Vlad and Trouble at MIT

Idea: mesanu

Tutorial

Solution coded by Dominater069, thanks!

Solution
Разбор задач Codeforces Round 928 (Div. 4)
  • Проголосовать: нравится
  • +69
  • Проголосовать: не нравится

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

For Problem-F, I have a bitmask dp solution: 247350477

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

    I am interested to know how you formed intitution for bitmask dp when it looks like a graph based problem at first.

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

      Firstly, I thought if we precalculate answers for all matrixes at the beginning, then we can solve queries in $$$O(n^2)$$$ which equals reading matrix.

      But how can we precalculate answers for all matrixes. Like in the editorial, we can separate matrix into 2 sets; which one of them has 25 elements, other's 24. How can we calculate answers for all matrix designs in one set.

      And then I reduced problem to a bitmask DP problem. And I found a classicial DP solution:

      Try to show possible matrixes as a masks, which black square is 1, else 0. Then $$$f(mask)$$$ will show answer for $$$mask$$$.

      We have 2 easy cases:

      1. It is a good matrix (every black square doesn't have 4 diagonal black square) and $$$f(mask) = 0$$$: We can check it in $$$O(bit \ number \ of \ mask)$$$.

      2. It isn't a good matrix, and suppose we transform $$$k.$$$ black square to white: $$$f(mask) = \min_{\forall k \in mask} f(mask \otimes 2^k) + 1$$$ And our case will has a same complexity as 1. case.

      Then we will have $$$2^{25}$$$ mask for first set, and $$$2^{24}$$$ for second set. And final complexity will be $$$O((2^{25} + 2^{24}) \times 25 + (T \times 49))$$$ or $$$O(2^{\frac{N^2}{2}} \times N/2 + T)$$$. Nearly $$$2 \times 10^9$$$ which is in TL. But it is too close to TL so it can get TLE if your constant is big.

      Note: You can fast your solution with magical bitwise operations.

      Also sorry for my poor English.

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

    great solution , can you share any resources from where I can learn it?

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

I tried hard to solve F using bipartite matching but I failed. Does F can't be solved by bipartite matching? I think it can be solved by find minimum vertex cover with good network modeling. Plz help me.

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

problem f is so bad i cant solve it

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

There's a much simpler solution for G.

  1. Root the tree.
  2. Do DFS
  3. if your current node $$$u$$$ is P, install a wall between $$$u$$$ and every child node $$$v$$$ that has S. The same goes for S.
  4. if your current node $$$u$$$ is C:
    • let $$$cnt_s$$$ be the number of childs have S.
    • let $$$cnt_p$$$ be the number of childs have P.
    • if $$$cnt_s \lt cnt_p$$$, add $$$cnt_s$$$ to the answer and change the letter on $$$u$$$ to P (Changing the letter to P means that the parent of $$$u$$$ should never be S since we have some unwalled edges contain P).
    • if $$$cnt_s \gt cnt_p$$$, the opposite of the previous step.
    • if $$$cnt_s = cnt_p$$$, It doesn't matter whether we should change $$$u$$$ to S or P (We should change it to be the same as the parent) so we left it to be C as it's.
»
2 года назад, скрыть # |
Rev. 2  
Проголосовать: нравится 0 Проголосовать: не нравится

I recorded myself live while solving A,B,C,D,E and thinking G. Hope it helps someone: https://www.youtube.com/watch?v=Zr2JbyTwq0A

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

Why this solution get TLE? https://mirror.codeforces.com/contest/1926/submission/247402006 I can't think of a single reason, every operation in loops are constant

I solved it other way: https://mirror.codeforces.com/contest/1926/submission/247402620 But still curious why first one is TLE

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

I wrote this solution which just check each line if it has substring of "010" since k>1 that means a square is at least 2*2

if it has a "010" then it is a triangle else is square

its an easier approach

Solution
»
2 года назад, скрыть # |
Rev. 10  
Проголосовать: нравится +12 Проголосовать: не нравится

I have a bitmask dp solution for problem F.

first assume that B = 1 and W = 0, and change the grid accordingly.

Let's say the bit on cell (i, j) is bad iff grid[i][j] = 1 and grid[i - 1][j - 1] = 1 and grid[i - 1][j + 1] = 1.

With that, let's define dp[i][j][k] to be the minimum number of flips considering the first i lines, the current mask on the i'th line is j, and k is a bitmask saying which bits from j are bad. Clearly, k is a submask of j, since the x'th bit from j can only be bad if grid[i][x] = 1, this is important because now we can iterate on j and k in $$$O(3^N)$$$. Now we need to transition to i + 1. How? simple, just iterate on all possible masks, and check if they are valid.

A mask is valid iff for all x, if x is bad than mask CANNOT have both (x — 1) and (x + 1) BOTH on. otherwise we would have that grid[i - 1][x - 1] = 1 and grid[i - 1][x + 1] = 1 and grid[i + 1][x - 1] = 1 and grid[i + 1][x + 1] = 1, which we cannot have.

With some clever preprocessing of the masks, this dp can be achieved with a complexity of $$$O(N * 2^N * 3^N)$$$, with N = 7 and 200 testcases, this is fast enough

here's my solution

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

I solve problem C without precomputing in O(t*log10(n)).LOL 247319547

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

I have a different approach with dp for problem F. First consider the following dp: dp[i][msk1][msk2].
i = current line
msk1 = what is the state of the last line
msk2 = what are the positions that, if we put two black cells in the diagonal in this line will make a X.
The transition for this dp will be: try every mask, see if the mask is possible and, if possible, calculate the cost of the mask.
The complexity of this would be O(7*2^7*2^7*2^7*7), and this is too slow for 200 test cases. But we can formulate the masks with a different way, take a number in base 3.
if the digit at pos j =
0: the pos j at last line was a W.
1: the pos j at last line was a B, and I can put two black cells in the diagonal.
2: the pos j at last line was a B, and I can't put two black cells in the diagonal.
This dp will be O(7*3^7*2^7*7), this will be sufficient for 200 test cases.
https://mirror.codeforces.com/contest/1926/submission/247403810

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

For problem D, rather than using XOR, I simply added the two numbers and checked to see if they were equal to 2^31 - 1. Here was my submission: 247301401. I then sorted the array and used two pointers. Is the editorial solution superior to mine? If so, why?

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

The link to G in the tutorial is in russian for some reason.

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

have problem with reading problem statement E. wouldn't all cards with number from 1 to n appears? for example 8, it's clearly not odd, it can't be 2 * (any odd number) number, it can't be 3 * (any odd number), it can't be 4 * (any odd number). 8 never appears, thus constraint on k, n is not valid

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

So is there a polynomial solution for F? I tried modeling with network flow but failed, and I think such approach probably won't work.

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

For F,my submission 247420824, why i add the dfs branch (the //add part),the result become worse. For example,

1
BBBWBBB
BBBBBBB
BBBBBBB
BBBBBBB
BBBBBBB
BWBWBBB
BBWBBWB

If I remove the comment symbols in the code and dfs by five cases, I get a result of 7.While following the code inside my link to dfs with three cases gives a result of 6.

Besides , What is the problem with the code inside my link and why can't AC.

Sorry for my poor English, can anyone help me ?

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

    I found the problem, I forgot to add "return" in this place during dfs

    if (check(x, y) == 0)
            "return" dfs2(u + 1, cnt);
    

    This can lead to otherwise legal points that I still go to enumerate to modify its diagonal, resulting in a large answer. And the more cases of dfs, the more likely it is to lead to a large answer, which is what led to my question above.

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

How can I do hash collision on this solution?

from collections import defaultdict

t = lol()[0]
int_max = 2**31-1
for _ in range(t):
    n = int(input())
    a = list(map(int, input().split())
    c = defaultdict(int)
    count = 0
    for e in a:
        if c[int_max ^ e]:
            count += 1
            c[int_max ^ e] -= 1
        else:
            c[e] += 1
    print(count + sum(c.values()))
»
2 года назад, скрыть # |
 
Проголосовать: нравится +10 Проголосовать: не нравится

I don't get why dp is needed in G. Isn't it simple dfs?

#include <bits/stdc++.h>
using namespace std;
const int int_max = 1e5 + 10;
char s[int_max];
vector<int> children[int_max];
int n;
 
int dfs(int i){
    int sm = 0;
    for (int j = 0; j < children[i].size(); j++){
        sm += dfs(children[i][j]);
    }
    int count_p = 0;
    int count_s = 0;
    for (int j = 0; j < children[i].size(); j++){
        if (s[children[i][j]] == 'P'){
            count_p++;
        }
        else if (s[children[i][j]] == 'S'){
            count_s++;
        }
    }
    if (s[i] == 'P'){
        return sm + count_s;
    }
    else if (s[i] == 'S'){
        return sm + count_p;
    }
    else{
        if (count_p > count_s){
            s[i] = 'P';
            return sm + count_s;
        }
        else if (count_p < count_s){
            s[i] = 'S';
            return sm + count_p;
        }
        else{
            return sm + count_p;
        }
    }
}
 
void solve(){
    cin >> n;
    for (int i = 0; i <= n; i++){
        children[i].clear();
    }
    for (int i = 2; i <= n; i++){
        int e;
        cin >> e;
        children[e].push_back(i);
    }
    for (int i = 1; i <= n; i++){
        cin >> s[i];
    }
    cout << dfs(1) << '\n';
}
 
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    int t;
    cin >> t;
    while(t--){
        solve();
    }
    return 0;
}
»
2 года назад, скрыть # |
 
Проголосовать: нравится +18 Проголосовать: не нравится

I would like to mention my solution for F.

Observation 1: Grid can be divided into 2 independent sets of cells based on whether (i+j) is odd or even, with 25 and 24 cells in each.

Considering only black cells, we can brute force all possible flips in O(2^25 * 25). But this is slow.

Observation 2: Flipping cells from the grid boundary is not necessarily needed, we will still find an optimal flipping.

This reduces our cell count to 13 and 12. And the brute force is fast enough now.

Code

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

My solution in C was $$$O(N + t)$$$ 247266041. If $$$n \le 10^6$$$ my solution will still work

But it contains precomputation too

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

A very simple solution for B. find the first instance of 1 in the grid. then check if the next cell is 1 and if the bottom cell is 1. if so then its square otherwise triangle.

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

for problem D i got TLE. I believe its o(n) can someone correct

from collections import Counter

for i in range(int(input())):
    n = int(input())
    a = list(map(int, input().split()))
    c = Counter(a)
    count = 0
    for e in a:
        k = 2147483647-e
        if c[k] and c[e]:
            count+=1
            c[e]-=1
            c[k]-=1
    print(n-(count))
»
2 года назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

As a nooooooooooob,even I can't solve D and E lol Next I will record the results of each of my races. I believe I can be LGM before 2026!

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

For problem B, I have a solution in which I get the numbers of 1s in the first line the number 1 starts appearing.

If the numbers of 1s in the next line that has 1 is different (for example, line 1 has 3 ones, line 2 has 1 one) then it is a triangle, otherwise it is a square. However this solution doesn't work on test case 2 and I've not been able to find any edgecase in my mind that defies this logic: 247338503

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

how to solve F in polytime?

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

I think this Div4 is harder than previous Div4, because problem F and G was very hard for pupil

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

Problem C: Why does it fail on Test #8 ? : Submission

`

include <bits/stdc++.h>

using namespace std;

int sumDigits(int n) { int sum = 0; while(n > 0) { sum += n%10; n /= 10; }

return sum;

}

void solve(vector v, int n, vector &copy) { map <int, int> mp; int ans = 0; int p = 0; for(int i = 1; i <= n; i++) { if(i == v[p]) { ans += sumDigits(i); mp[i] = ans; p++; continue; } else ans += sumDigits(i); }

for(int i = 0; i < copy.size(); i++) {
    cout << mp[copy[i]] << endl;
}

}

int main() { ios::sync_with_stdio(0); cin.tie(0);

int t; cin >> t;
int maxN = 0;
vector<int> v;
while(t--) {
    int n;
    cin >> n;
    maxN = max(maxN, n);
    v.push_back(n);
}

vector<int> copy = v;
sort(v.begin(), v.end());
solve(v, maxN, copy);

return 0;

} `

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

For Problem-F, we just need to check the cells marked as '@' below:

. . . . . . .
. . @ @ @ . .
. @ @ @ @ @ .
. @ @ @ @ @ .
. @ @ @ @ @ .
. . @ @ @ . .
. . . . . . .

For the blue part, we need to check these cells:

. . . . . . .
. . @ . @ . .
. @ . @ . @ .
. . @ . @ . .
. @ . @ . @ .
. . @ . @ . .
. . . . . . .

So we just brute force from 0 to 4095.

For the red part, we need to check these cells:

. . . . . . .
. . . @ . . .
. . @ . @ . .
. @ . @ . @ .
. . @ . @ . .
. . . @ . . .
. . . . . . .

So we just brute force from 0 to 511.

Here is my solution: 247559944.

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

For problem C I've a O(n) solution which runs in about 15 ms (c++) 247602474

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

How to deal with Problem C if n<=1e18. (Chinese student,Englishi is very poor...)

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

    That means how to deal it with a O(t) solution. I think there is a solution which used math.

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

      I don't sure but i think my solution here is O(log(n)) for each query

      #include <bits/stdc++.h>
      using namespace std;
      #define ll long long
      
      ll sumOfDigits(ll n) {
          if (n < 10)
              return n * (n + 1) / 2;
      
          ll d = log10(n);
          ll *a = new ll[d+1];
          a[0] = 0, a[1] = 45;
          for (ll i = 2; i <= d; i++)
              a[i] = a[i-1] * 10 + 45 * ceil(pow(10, i-1));
      
          ll p = ceil(pow(10, d));
          ll msd = n / p;
      
          return msd * a[d] + (msd * (msd - 1) / 2) * p + msd * (1 + n % p) + sumOfDigits(n % p);
      }
      
      int main() {
          ios_base::sync_with_stdio(false);
          cin.tie(0); cout.tie(0);
      
          int t;
          cin >> t;
          while(t--) {
              ll n;
              cin >> n;
              cout << sumOfDigits(n) << "\n";
          }
      
          return 0;
      }
      
      • »
        »
        »
        »
        2 года назад, скрыть # ^ |
         
        Проголосовать: нравится 0 Проголосовать: не нравится

        Thanks for your healping.Last night I solve Problem C with a O(log10 n * t) solution.This is my code:

        #include<bits/stdc++.h>
        using namespace std;
        #define pii pair<int,int>
        #define mp(x,y) make_pair(x,y)
        #define pqg priority_queue<int,vector<int>,greater<int>>
        #define pql priority_queue<int,vector<int>,less<int>>
        #define pqg_pii priority_queue<pii,vector<pii>,greater<pii>>
        #define pql_pii priority_queue<pii,vector<pii>,less<pii>>
        #define scnaf scanf
        #define rt register int
        #define int long long
        int n,T,a[6],x[6],k[6];
        string s;
        signed main() {
        //	freopen(".in","r",stdin);
        //	freopen(".out","w",stdout);
        	cin>>T;
        	k[0]=45;
        	for(int i=1; i<5; i++)
        		k[i]=k[i-1]*10+45*pow(10,i);
        	cout<<endl;
        	while(T--) {
        		cin>>s;
        		int ans=0;
        		a[0]=a[1]=a[2]=a[3]=a[4]=0;
        		x[0]=x[1]=x[2]=x[3]=x[4]=0;
        		n=s.size();
        		for(int i=0; i<n; ++i)
        			a[i]=s[i]-'0';
        		for(int i=1; i<n; ++i)
        			x[i]=x[i-1]+a[i-1];
        		for(int i=0; i<n/2; ++i)
        			swap(a[i],a[n-i-1]),swap(x[i],x[n-i-1]);
        		if(a[0]!=0)
        			ans=(a[0]+1)*a[0]/2+a[0]*x[0];
        		for(int i=1; i<n; i++)
        				ans+=a[i]*pow(10,i)*x[i]+k[i-1]*a[i]+a[i]+(a[i]-1)*a[i]*pow(10,i)/2;
        		cout<<ans<<endl;
        	}
        	return 0;
        }
        
»
2 года назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

I think problem F can further be optimized by considering only the inner 5x5 square (the same idea, just considering less squares for backtrack). This approach should be more than 10x faster.

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

I made video editorial for problem G.

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

For problem E. What I did is I observed the pattern that it was forming and then I calculated the row in which my no is coming and then i found the position where the no will be and then found out the odd no corresponding to that position and then ans is (oddno*(1<<rowno)),

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

can problem E be proven mathematically? the fact that the next power of 2 times odd does not contain the previous power of 2 times odd?

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

for problem F, we can bruteforce but the can reduce the search space to 12 cells for first case and 9 cells for the other. we can prove in atmost 4 operations are required per case. which gives N.M.(12C4 + 9C4) which is nearly ~600.N.M its quite fast obviously..

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

flamestorm Can you pls explain difference between C question and this CodeChef question ro27 https://www.codechef.com/problems/OG

this is accepted in codechef

ll n; cin>>n;
ll r = n%9;
ll ans = (n/9)*45;
ans+=(r*(r+1)/2);
cout<<ans<<"\n";

but same code is not working for 1st test case in CF.