atcoder_official's blog

By atcoder_official, history, 9 months ago, In English

We will hold AtCoder Beginner Contest 416.

We are looking forward to your participation!

  • Vote: I like it
  • +55
  • Vote: I do not like it

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

Hi! Good luck guys

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

Good luck and have fun guys!

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

Good luck,everyone!Have a fantastic grade,bro!

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

Good luck!

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

Good luck guys

»
9 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it
New Bee
»
9 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

How did you approach C and D, Can you explain your thinking process?

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

    I solved C by using backtrack, the constraint of the X in Cth questions works as a hint. can't be able to solve D

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

    C — recursion + backtracking

    D — sort both the arrays and use two pointers

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

    C is brute force as k is upto 5 and n is upto 10.

    we can generate all possible subsets and select subset size of given k . sort the strings formed in these k sized subsets. print xth string from sorted array.

    https://leetcode.com/problems/subsets/ -- can be helpful.

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

      Can you tell me why this fails? I think C was easy too, but I guess I am missing something and also we can't see test cases for AtCoder. (;-;)

      Your code here...
      #include <bits/stdc++.h>
      using namespace std;
      
      bool valid(string s, int n)
      {
          for (char c : s)
          {
              int d = c - '0';
              if (d >= n)
                  return false;
          }
          return true;
      }
      void solve()
      {
          int n, k, x;
          cin >> n >> k >> x;
      
          vector<string> stringVec(n);
          for (string &x : stringVec)
              cin >> x;
          sort(stringVec.begin(), stringVec.end());
      
          int start = 0;
          int m = n - 1;
          string e(k, m + '0');
          // cout << "e : " << e << endl;
          int last = stoi(e);
      
          vector<string> need;
          for (int i = start; i <= last; i++)
          {
              string s = to_string(i);
              int slen = s.length();
              if (slen < k)
              {
                  int rem = k - slen;
                  string pad(rem, '0');
                  s = pad + s;
              }
      
              if (valid(s, n))
              {
                  need.push_back(s);
              }
          }
      
          string build = need[x - 1];
          string ans = "";
          for (char c : build)
          {
              int d = c - '0';
              ans += stringVec[d];
          }
      
          cout << ans << endl;
      }
      int main()
      {
          solve();
          return 0;
      }
      
  • »
    »
    9 months ago, hide # ^ |
    Rev. 2  
    Vote: I like it +3 Vote: I do not like it

    C is just generate all possible strings, sort them and output the x-th element.

    D was a bit tough for me (maybe because I was trying to find the pairs with sum like 0 or m). But then after trying some values, I realized that I need to find more pairs where sum>=m. Then it was just binary search and sorting.

    E was a good one.

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

Idea behind F ?

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

    did you solve D ? please share the intuition behind it

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

      you can read all elements mode M, then use lower_bound() to find the optimal choice! sort on of them in non-increasing order, because it's more easy to fill the gaps when it still just small sizes at the end, it's the problem of make to tower such that the diff between them is minimal

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

Is E Floyd warshall?

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

https://mirror.codeforces.com/contest/1157/problem/E the same problem D in the contest just replace n with m ^_^

»
9 months ago, hide # |
Rev. 4  
Vote: I like it +1 Vote: I do not like it

got stuck on both C and D... there a ~3000 rank and ~600 performance gap between those who finished ABCD fastest and slowest...

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

    How to see the rating change like shown in the picture? I always need to wait for couple hours before the website update

    • »
      »
      »
      9 months ago, hide # ^ |
      Rev. 2  
      Vote: I like it +1 Vote: I do not like it

      search "AC-predictor" in greasyfork.org and download the userscript (you need to install tampermonkey in your google first)

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

Nice solution for E. The idea of using a sky node is very elegant.

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

how to approach on problem D? I got stuck on D ...

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

    start by read all elements Mod M, then try to link each element from array A to it's complement on array B if exists, if not, try the closest one

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

    just code: ~~~~~~~

    Your code here...
    int n,m;
    cin>>n>>m;`
     multiset<int>a,b;
        for(int i=0;i<n;i++){
           int x;cin>>x;
           a.insert(x);
        }
        for(int i=0;i<n;i++){
           int x;cin>>x;
           if(a.count(m-x)){ //it turns out that 0 and that is minimum
            a.erase(a.find(m-x));
           }
           else b.insert(x);
        }
        int ans=0;
        for(auto u:a){
            int y=*b.rbegin();
            if(y+u>m){  //in this case (y+u)%m is definately smaller than u which gives minimum
                ans+=(y+u)%m;
                b.erase(b.find(y));
            }
            else{ //add the smallest value from b which gives minimum 
                ans+=(*b.begin()+u)%m; 
                b.erase(b.find(*b.begin()));
            }
        }
      cout<<ans<<nl;
    

    `

    ~~~~~~~

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

    Thanks for comments!

»
9 months ago, hide # |
Rev. 8  
Vote: I like it +13 Vote: I do not like it

Problem G can be solved in $$$O(N|S_\max| + |S_\max|^4)$$$ (where $$$|S_\max| = 10$$$), which is more efficient than the $$$O(K|S_\max|^2)$$$ solution in the editorial.

First, we define a string set $$$T$$$, called "the set of strings that might be the answer."

Next, we consider how to find these strings in the set. We first sort the strings in $$$S$$$ lexicographically in ascending order.

String $$$S_1$$$ is definitely a candidate, so we add it to $$$T$$$.

At this point, any string that might be the answer must start with $$$T_1$$$ as a prefix.

Thus, we directly brute-force check whether $$$S_2$$$ can be a valid string, with a time complexity of $$$O(|S|^2)$$$. The method works by maintaining two pointers, $$$i = 0$$$ and $$$j = 0$$$, and incrementing them as $$$i \gets (i+1) \mod |S_1|, j \gets (j+1) \mod |S_2|$$$. If $$$S_{1,i} \gt S_{2,j}$$$, then $$$S_2$$$ is not a valid answer. If $$$S_{1,i} \lt S_{2,j}$$$, then $$$S_2$$$ might be an answer, and we add it to $$$T$$$.

By following this approach, we find that only the first $$$|S_\max|$$$ elements might be valid answers. Therefore, the time complexity for this part is $$$O(|S_\max|^3)$$$.

When $$$k = \infty$$$, using $$$T_{m=|T|}$$$ repeatedly would be optimal, but since $$$k$$$ is finite, we need to consider how to maintain this.

We observe that the answer must have the following structure:

A certain number of $$$T_m$$$, followed by a certain number of $$$T_{m-1}$$$ (which could be zero), followed by a certain number of $$$T_{m-2}$$$ (which could be zero), and so on, ending with a certain number of $$$T_1$$$ (which could also be zero).

Therefore, we can use dynamic programming (DP), where $$$f_{i,j}$$$ represents the lexicographically smallest string that can be formed using elements from $$$T_{\leq i}$$$, totaling $$$j$$$ elements.

The transition for this DP can be done in $$$O(|T|K^3)$$$, which includes the complexity for string concatenation.

We find that $$$K$$$ is a bit troublesome, but we make a bold assumption: for the first $$$k - |S_\max|^2$$$ strings, we only pick $$$T_m$$$, and only the last $$$|S_\max|^2$$$ strings need further processing.

Here, we discard the DP and directly apply the approach from the official editorial, achieving $$$O(|S_\max|^4)$$$.

Finally, we realize that the previous sorting step is unnecessary. We can directly build a Trie and traverse it to find the first $$$|S_\max|$$$ strings.

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

    o, maybe it can be $$$O(N|S|+|S|^4)$$$ by use editorial's solution in the last step.

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

      Using the editorial, you can solve for arbitrary $$$K$$$ (given that you can output the solution, you can have a bunch of queries at positions where you're asked to print what is the character at said position) in $$$\mathcal{O}(|S_{max}|^3 \log{K})$$$. You compute $$$d_{i, j, t}$$$ = using $$$2^t$$$ strings, what is the shortest string that matches $$$T_{\infty}$$$ starting at position $$$i \mod |S_{max}|$$$ and ending at position $$$j \mod S_{max}$$$ and do matrix exponentiation on that and then you do exponentiation.

      To build the base matrix, for each pair $$$(i, j)$$$, you check whether there is a string that matches that part and if there is, you put the length of that string, or if it not, then you set $$$\infty$$$. Then you do exponentiation with $$$* = +$$$ and $$$+ = \max$$$.

»
9 months ago, hide # |
 
Vote: I like it +14 Vote: I do not like it

E question is so disgusting! The input a, b, and c actually have the same side, so I adjusted it for 40 minutes!

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

https://atcoder.jp/contests/abc416/submissions/67945292 Can someone help me find the counter test case for my solution ?!

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

when will rating get updated?

»
9 months ago, hide # |
 
Vote: I like it +5 Vote: I do not like it

I think today's ABC is good as well. From problem C to F, the topics are [dfs or backtrack], [greedy + binary search or two pointers], [floyd], [dp on trees].

By the way, my solution to problem F is a little bit different from that in editorials.

I use dp[u=1/2/.../n][j=0/1/2][p=0/1/2.../k] to denote the maximum values, where

u denotes the subtree of node-u

j = 0 denotes that node-u is white

j = 1 denotes that node-u is black, and there is still a chance to extend the path to its parent

j = 2 denotes that node-u is black, but we can not extend the path to its parent anymore

p denotes the number of black paths we already have.

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

Had a bruh moment on E.

I did:

int a, b, c;
cin >> a >> b >> c;
dist[a][b] = c;
dist[b][a] = c;

instead of

int a, b, c;
cin >> a >> b >> c;
dist[a][b] = min(dist[a][b], c);
dist[b][a] = min(dist[a][b], c);

Kept getting WA :(

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

Can someone please help me with D, I have everything AC except 2 test cases which are TLE. Here's my code:


~~~~~ #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #pragma GCC target("popcnt") #define endl '\n' using namespace std; using namespace __gnu_pbds; const int dim = 2e5+7; const int mod = 1e9+7; const long long inf = 625e9+1; typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> superset; int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int t; cin >> t; while(t--) { int n,m; cin >> n >> m; vector<int> a(n),b(n); for(int i=0;i<n;i++) cin >> a[i]; for(int i=0;i<n;i++) cin >> b[i]; sort(a.begin(),a.end()); sort(b.begin(),b.end()); long long sum = 0; for(int i=0;i<n;i++) { auto stat = lower_bound(b.begin(),b.end(),m-a[i]); int pos = stat-b.begin(); if(stat!=b.end() && (a[i]+b[pos])%m<(a[i]+b[0])%m) { sum+=(a[i]+b[pos])%m; b.erase(stat); } else { sum+=(a[i]+b[0])%m; b.erase(b.begin()); } } cout << sum << endl; } return 0; }

~~~~~

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

D and E are good problems (though I didn't solve them during the contest)

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

I don't understand D, can someone please explain its approach to me and it will be very helpful if you could give me the proof of the solution that you came up with..

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

Can anyone explain there approach for F ....cant understand the editorial

»
9 months ago, hide # |
 
Vote: I like it -13 Vote: I do not like it

https://atcoder.jp/contests/abc416/submissions/68006865

i've read the editoral for E, i already build a sky node, multi edges, and etc but kept getting WA, can anyone help pls

jpr[i] = minimum distance to go to the sky for node i

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

    The floyd warshall looks a bit different from what I'm used to.

    void floyd_warshall(int n) {
        // floyd warshall, all pairs shortest path
        for (int k = 0; k < n; k++) {  // Intermediate vertex
            for (int i = 0; i < n; i++) {  // Source vertex
                for (int j = 0; j < n; j++) {  // Destination vertex
                    if (dist[i][k] == INF || dist[k][j] == INF) continue;
                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
                }
            }
        }
    }
    
  • »
    »
    9 months ago, hide # ^ |
     
    Vote: I like it +6 Vote: I do not like it

    hey kang, I think you need to learn more about Floyd warshall especially the proofing behind the iteration, since u got the iteration wrong. good luck!

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

Please, someone help, keep getting wa on E, here's my code:

//This code was written on my laptop (2025)
/*Powered by STEPAN SIMAK*/
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC target("popcnt")
#define endl '\n'
using namespace std;
using namespace __gnu_pbds;
const int dim = 2e5+7;
const int mod = 1e9+7;
const long long inf = 5e11+1;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> superset;
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int test;
    test = 1;
    while(test--) {
        long long n,m,k,t,q;
        cin >> n >> m;
        vector<vector<long long>> g(n+1,vector<long long>(n+1,inf));
        for(int i=1;i<=m;i++) {
            long long v1,v2,w;
            cin >> v1 >> v2 >> w;
            g[v1][v2] = min(g[v1][v2],w);
            g[v2][v1] = min(g[v1][v2],w);
        }
        cin >> k >> t;
        for(int i=1;i<=k;i++) {
            int d;
            cin >> d;
            g[d][0] = t;
            g[0][d] = 0;
        }
        for(int k=0;k<=n;k++) {
            for(int i=0;i<=n;i++) {
                for(int j=0;j<=n;j++) {
                    if(i==j) g[i][i] = 0;
                    g[i][j] = min(g[i][j],g[i][k]+g[k][j]);
                }
            }
        }
        cin >> q;
        for(int i=1;i<=q;i++) {
            long long type,x,y,tt;
            cin >> type;
            if(type==1) {
                cin >> x >> y >> tt;
                g[x][y] = min(g[x][y],tt);
                g[y][x] = min(g[y][x],tt);
                for(int i=0;i<=n;i++) {
                    for(int j=0;j<=n;j++) {
                        g[i][j] = min(g[i][j],min(g[i][x]+g[x][j],g[i][y]+g[y][j]));
                    }
                }
            }
            if(type==2) {
                cin >> x;
                g[x][0] = min(g[x][0],t);
                g[0][x] = min(g[0][x],0ll);
                for(int i=0;i<=n;i++) {
                    for(int j=0;j<=n;j++) {
                        g[i][j] = min(g[i][j],min(g[i][x]+g[x][j],g[i][0]+g[0][j]));
                    }
                }
            }
            if(type==3) {
                long long ans = 0;
                for(int i=1;i<=n;i++) {
                    for(int j=1;j<=n;j++) ans+=(g[i][j]%inf);
                }
                cout << ans << endl;
            }
        }
    }
    return 0;
}

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

I know brutal force can solve C, but I just wonder how is the idea below failed? If anyone can share a test case that would be great. thanks in advance!

public class ABC416_C {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("input.in"));
//         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        StringTokenizer st = new StringTokenizer(br.readLine());
        long n = Long.parseLong(st.nextToken());
        long k = Long.parseLong(st.nextToken());
        long x = Long.parseLong(st.nextToken());
        List<String> lst = new ArrayList<>();
        for(int i = 0;i < n;i++){
            lst.add(br.readLine());
        }
        Collections.sort(lst);
        long loop = k;
        for(int i = 0;i < loop;i++){
            int p = 0;
            long bulk = 1;
            for(int j = 0;j < k -1;j++){
                bulk *= n;
            }
            while(x > bulk){
                x -= bulk;
                p++;
            }
            System.out.print(lst.get(p));
            k--;
        }

        br.close();
    }
}