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

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

Thanks for participating!

1703A - YES or YES?

Idea: flamestorm

Tutorial
Solution

1703B - ICPC Balloons

Idea: flamestorm

Tutorial
Solution

1703C - Cypher

Idea: mesanu

Tutorial
Solution

1703D - Double Strings

Idea: MikeMirzayanov

Tutorial
Solution

1703E - Mirror Grid

Idea: mesanu

Tutorial
Solution

1703F - Yet Another Problem About Pairs Satisfying an Inequality

Idea: flamestorm

Tutorial
Solution

1703G - Good Key, Bad Key

Idea: mesanu

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

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

Quickly

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

    most satisfying G solution : state : dp[i][j] means at ith element we use exactly j bad keys. trans : either we have to use bad key at ith place or it already been use before.

    #include <bits/stdc++.h>
    using namespace std;
    
    /* UserName SeniorLikeToCode [Abhishek Gupta (AKGEC 3rd year)]; */
    
    #define int     long long
    #define endl    '\n'
    
    void solve() {
        int n, k; cin >> n >> k;
        vector<int> a(n); for (auto &i : a) cin >> i;
    
        int dp[n + 1][40], ans = 0;
        memset(dp, 0, sizeof(dp));
    
        for (int i = 0; i < n; i++) {
            dp[i + 1][0] = dp[i][0] + a[i] - k;
            for (int d = 0; d <= min(32ll, i + 1) ; d++) {
                dp[i + 1][d + 1] = max(dp[i][d + 1] + (a[i] >> (d + 1)) - k, dp[i][d] + (a[i] >> (d + 1)));
            }
        }
        for (int i = 1; i <= n; i++) for (int d = 0; d <= 33; d++) {
            ans = max(ans, dp[i][d]);
        }
    
        cout << ans << endl;
    }
    
    signed main() {
        ios_base::sync_with_stdio(NULL);
        cin.tie(NULL); cout.tie(NULL);
    
        int test = 1; cin >> test;
        while (test--) solve();
    }
    
    
    • »
      »
      »
      3 года назад, скрыть # ^ |
       
      Проголосовать: нравится 0 Проголосовать: не нравится

      Hey I would like to request a clarification: why do you report answer as the maximum of dp[i][j] over all values of i and j? should it not be just maximum value of dp[n][j] over all values of j?

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

        I also want to ask this question,did you get the answer?

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

          Because of their definition "dp[i][j] means at ith element we use exactly j bad keys". Note that we can definitely use more than 33 bad keys, but it won't matter because after 33 bad keys all elements to the right will be 0. So, considering dp[i][j] for i < n is equivalent of handling all cases where a[k] becomes 0 for all k > i (note ai >= 0). If the definition was "at most j bad keys", then we could just answer max over j of dp[n][j], but the transition would be different.

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

        Sorry for the late reply, for the answer Think like you brute forcing and you can use j keys, now after using j keys, You dont know which previous step give you the best answer. So new question arises at any stage did we know the best answer ? the answer is "NO" , for any ith step we are checking complete ith step. That's the simplified reason why we are checking complete i * j for the last answer.

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

      the fact that you just need to iterate for around 30 bad keys was the main catch..without it every way of solving it takes n^2 TT

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

Thanks for fast tutorial

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

Amazing contest !! ..E is tricky one!

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

F is solvable with prefix sums in $$$O(n)$$$.

For each $$$i$$$ count the number of elements, where $$$j \leq i$$$ and $$$a_j \lt j$$$ ($$$pref_i$$$). And for each $$$i$$$ where $$$a_i \lt i$$$ just add $$$pref_{a_i-1}$$$ to the answer.

Here is my solution 163953789.

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

I will say that it was a good contest. Thanks for the quick tutorial

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

Hey! Can anyone clarify why my solution is showing TLE on Test Case 10 (Problem D), my approach is similar as that mentioned in the Editorial. Thanks! 163871330

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

I think problem F can be done in O(n) time.

As mentioned, we only need to consider indices i such that a_i < i. Call such indices "good". We can make a prefix array such that the ith element is the number of good indices less than or equal to i.

Now consider all possible pairs (i,j) that work for a fixed good index j. The number of possible values for i is the number of good indices less than a_j, which is stored within the prefix array. The answer can then be found by summing across all good indices j.

The prefix array can be created in 1 pass, so that takes O(n) time. The summing across all good indices can also be done in 1 pass, so this is O(n) time again.

Code for this can be found in my submission

Edit: Apparently got sniped lmao

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

Problem G was a good one.

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

For the problem D we can use unordered_set<string> cache to store the strings. Then for each string, bruteforrce divide the strings in two and check whether both of these strings exist in the cache or not. Simple

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

This code of mine for question D(double strings) is giving TLE on test 3 and I don't know why. Please help me where is the problem?

#include<bits/stdc++.h>
using namespace std;
#define ll long long int

char check_string(ll k,vector<string> &v){
    if(v[k].size() == 1) return '0';
    for(ll i=0;i<v.size();i++){
        if(i == k) continue;
        for(ll j=0;j<v.size();j++){
            if(j == k) continue;
            if(v[i]+v[j] == v[k]) return '1';
        }
    }
    return '0';
}

int main(){
    ll t;
    cin>>t;
    while(t--){
        ll n;
        cin>>n;
        vector<string> v(n);
        for(ll i=0;i<n;i++){
            cin>>v[i];
        }
        string s;
        for(ll i=0;i<n;i++){
            s += check_string(i,v);
        }
        cout<<s<<endl;
    }
    return 0;
}
»
4 года назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

Can F be solved by Fenwick tree??

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

Honestly, F was too easy with Segment Trees (or Fenwick Trees, those two have identical purposes). I think any person with some experience of common segment tree problems would easily solve it.

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

Let's see in the hacking phase if people learned to use the map instead of the unordered_map. beethoven97 I summon you!

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

why this solution 163935126 giving TLE ? Anybody please help

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

    because memset function fills the DP using its size --> O(N), here it is N = 1e5 so your dp gets filled for all test cases which can be upto 1e4, so ~1e9 operations per second are performed.

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

Thank you for the very good contest, all the problems are enjoyable

I learn some new thing from problem G

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

i tried to solve F with multiset (c++) along with lower_bound, distance methods here: link

but i get TLE, why?

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

Can anyone tell why using vector in this solution for problem E gives wrong answer? Replacing vector with plain array makes it accepted. Submission link

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

someone hacked my D (163901816) can anyone provide me test case ?

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

DP solution for G. Lang: PyPy3-64 ____________________________________________________________________________________

t = int(input())
 
 
for _ in range(t):
    n, k = map(int, input().split())
    *arr, = map(int, input().split())
 
    MAX_HALF_CNT, NINF = 1, -2**63
    max_coins = max(arr)
    while max_coins >> MAX_HALF_CNT:
        MAX_HALF_CNT += 1
    MAX_HALF_CNT += 1
 
    dp = [[NINF] * MAX_HALF_CNT for _ in range(n)]
    # dp[i][half_cnt] 打开第i个抽屉后所能得到的最大硬币数,其中使用了half_cnt次坏钥匙,
 
    dp[0][0] = arr[0] - k # 用好钥匙,减k
    dp[0][1] = (arr[0] >> 1) # 用坏钥匙,减半
    # print(dp)
    for i in range(n-1):
        for h in range(MAX_HALF_CNT):
            dp[i+1][h] = max(dp[i+1][h], dp[i][h] + (arr[i+1] >> h) - k)
            if h + 1 < MAX_HALF_CNT:
                dp[i+1][h+1] = max(dp[i+1][h+1], dp[i][h] + (arr[i+1] >> (h + 1)))
            else:
                # 啥都没了
                dp[i+1][h] = max(dp[i+1][h], dp[i][h] + 0)
 
    print(max(dp[n-1]))

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

Could help me G problem?i use dp to slove it ,but i cant fine my problem.thank u very much

problem G

TAT...my english is poor ,but i try to share my idea

j:the number of good key

pw(2,x)=2**x

when we open the i th box ,if we use j good keys so we use (i-j) bad keys.but pw(2,33)>1e9,so i think the number of good key is lower than 33.

if the number of bad key is upper than 33,we can see it as 1e14.

so when we open some box,if we use good keys ,we got a[i]/(pw[(i-j)] -m cost

and we use bad keys ,we got a[i]/(pw[(i-j)] -m

so DP[i][j] is mean open i boxes use j good keys.

Dp[i][j]=Dp[i-1][j]+ bad keys or DP[i][j]=DP[i-1][j-1] + good keys

so whats wrong with me TAT

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

    Suppose that n and k are very large And the optimal operations are always use bad keys. In this case obviously we use more than 32 bad keys but your solution don't considers this and gives the wrong answer.

    To fix it : for calculating answer iterate over all dp values and get maximum instead of only dp[n — 1] (because if we do this we consider above case):

    for(int i = 0; i < n; i++)
       for(int j = 0; j < 32; j++)
           ans = max(ans, dp[i][j]);
    

    My submission : 163915709

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

For first 30 minutes i think in E we need to make matrix by add 1. Later i eays accepted this Problem

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

Thanks for the fast editorial

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

Another F approach. We can create p where p[i] = (a[i] < i), after that create a prefix sum on that array and iterate over a and do the following:

  • check if p[i] = 1, otherwise continue
  • check if a[i] >= 2, otherwise continue
  • add prefsum[a[i] — 1] to the answer

So why do we need a[i] >= 2 statement? If a[i] < 2, then there is no way to satisfy this inequality. a[i] >= 0, i >= 1, therefore a[i] < i < 1 < j can't be satisfied. Check out my implementation if you are interested 164005949. What do you think about this one?

P.S Well, just find out some guy already told about the same approach...

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

Simple recursive DP solution for G here.

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

map<string, bool>? Why not just use a set<string>?

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

Can someone tell me why this dp solution is getting WA, doesn't make any sense to me? https://mirror.codeforces.com/contest/1703/submission/163945776

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

Video Solutions of complete problemset.

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

F can be solved in linear time. submission

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

Ratings did not seem to update. Anyone else having this problem?

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

Can anyone please tell why am I getting Memory Limit Exceeded in Problem E? I am just using a 2D Array. Link to my submission :- https://mirror.codeforces.com/contest/1703/submission/163908463

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

I solved F in O(n) Here is my solution: 163897273

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

Good solution for problem G!

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

Can someone suggest more problems similar to G?(like DP states like this)

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

Deleted

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

In G, reason why we have to iterate over all dp array instead of only go through dp[n][0-32] is that during the transferation of dp array, once the second dimension hit the boundary, we would lose one stratey, which is using the bad key. Because we were supposed to do dp[i][33]=dp[i-1][33-1]+a[i]>>32(or 33?im not sure), but the boundary force us to only do dp[i][32]=dp[i-1][31]+a[i]>>32(?)-k, which is using the good key, taking all the cost painfully. so u see how the bad key strategy is lost during the process, besides iterating all dp array, we can also do dp[i][j]=dp[i-1][j-1] when a[i]>>j==0.

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

is there a formula shows where cell i,j maps to when rotate 90, 180, 270 degrees in problem E?

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

Very simple approach for Problem E: 350773731

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

1703B — ICPC Balloons Use a set to track which problems already appeared. If it’s the first time we see this character → +2. Otherwise → +1. Very beginner-friendly problem.

i hope this is helpful

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

A bit too late to comment here, hope it will help someone out. Simple O(n) solution for problem F

358822307

void solve() {
    int n; 
    cin >> n;
    vi a(n+1);
    for(int i = 1; i <= n; i += 1) cin >> a[i];
    vector<bool> is_good(n+1, false);
    for(int i = 1; i <= n; i += 1){
        if(a[i] < i) is_good[i] = true;
    }
    vi good_till(n+1, 0);
    for(int i = 1; i <= n; i+= 1){
        good_till[i] = good_till[i-1] + is_good[i];
    }
    int ans = 0;
    for(int i = 1; i <= n; i += 1){
        if(is_good[i] && a[i] > 0) ans += good_till[a[i]-1];
    }
    cout << ans << endl;
}
»
2 недели назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

zdorova

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

For G, the core idea is just using prefix sums to count valid choices based on neighbors. Submission: https://mirror.codeforces.com/contest/2218/submission/371601392.