atcoder_official's blog

By atcoder_official, history, 14 months ago, In English

We will hold KAJIMA CORPORATION CONTEST 2025 (AtCoder Beginner Contest 394).

We are looking forward to your participation!

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

| Write comment?
»
14 months ago, hide # |
 
Vote: I like it +63 Vote: I do not like it

If this ABC as shit as the last ABC, I will ban you.

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

it seems blogs of ABC get less and less upvotes even get downvotes.

upd: this round is worse than last one again.

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

Wish no more AI Best Contest plz.

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

painful

»
14 months ago, hide # |
 
Vote: I like it -18 Vote: I do not like it

Why ABC G. is so hard?

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

Problem E is very similar to [POI 2009] Bytie-boy's Walk.

In POI, it shows us that E can be solved with time complexity $$$O(n^2V+nm)$$$. ($$$V=26$$$, $$$m$$$ is the number of edges).

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

Why this gives TLE for E in 2 test cases ?

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

How to solve E?

»
14 months ago, hide # |
 
Vote: I like it -6 Vote: I do not like it

man how i do the c better than this ? Sorry my english is bad :(

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

#define f first
#define s second

bool temWA(string str){
    for(int i = 0; i < str.length() - 1; i++){
        if(str[i] == 'W' && str[i+1] == 'A') return true;
    }

    return false;
}


int main(){
    string str; cin >> str;
    
    while(temWA(str)){
        for(int i = 0; i < str.length() - 1; i++){
        if(str[i] == 'W' && str[i+1] == 'A'){
            str[i] = 'A';
            str[i+1] = 'C';
        }
    }
    }

    cout << str << endl;
}

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

Anyone could please provide a testcase for my submissión for problem D? I failed just two cases :')

My submission

Thanks in advance

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

after contest i tried with o3-mini it solves E in one shot after giving my intuition. my TLE code : https://atcoder.jp/contests/abc394/submissions/63054891 o3-mini code: https://atcoder.jp/contests/abc394/submissions/63064525

today's problem set was nice but D was way more easier than C for me

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

    I'm surprised to see the o3-mini code passing the time limit. The complexity is $$$O(n^4)$$$ and it takes 8s on a max test.

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

Why is this wrong for F Alkane?

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

    I had the same idea and i can't figure out what's wrong either...

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

    This is wrong because you can take the nodes which have degree > 4 in the original graph to be the part of the subgraph. You just need to ensure that in the subgraph the degree is exactly 4.

    E.g. case:

    6
    1 2
    1 3
    1 4
    1 5
    1 6
    

    Here in the original graph, the degree of node 1 is 5, your solution will ignore the node 1. But you can take nodes 1, 2, 3, 4, 5 and create an alkane out of them.

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

      OH Yes you are right , i mistakenly thought that given inputs are having degree of any node at max 4

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

The problems in ABC contests are becoming increasingly easier, making rankings largely dependent on the speed of coding.

e.g. slower 10 min will get nearly 1000 rank down

»
14 months ago, hide # |
 
Vote: I like it -6 Vote: I do not like it

For Problem F: My code is working on 1-39 testcases, and WA on 40-59, please find error...

Your code here...
void dfs(ll x, vector<bool>& vis,vector<set<ll>>& graph,ll& c)
{
    c++;
    vis[x]=true;
    for(ll i:graph[x])
    {
        if(!vis[i])
        {
            dfs(i,vis,graph,c);
        }
    }
}

void solve()
{
    ll n;
    cin>>n;
    vector<set<ll>> num(n+1);
    for(ll i=1; i<n; i++)
    {
        ll a,b;
        cin>>a>>b;
        num[a].insert(b);
        num[b].insert(a);
    }

    queue<ll> q;
    for(ll i=1; i<=n; i++) if(num[i].size()==1) q.push(i);

    ll ans=0;

    while(!q.empty())
    {
        ll x = q.front();
        q.pop();
        ll p = *num[x].begin();
        ll s = num[p].size();
        if(s==1)
        {
            num[x].erase(p);
            num[p].erase(x);
        }else if(s==2)
        {
            num[x].erase(p);
            num[p].erase(x);
            q.push(p);
        }else if(s==3)
        {
            num[x].erase(p);
            num[p].erase(x);
        }else if(s>4)
        {
            num[x].erase(p);
            num[p].erase(x);
        }
    }
    vector<bool> vis(n+1,false);
    for(ll i=1; i<=n; i++)
    {
        if(num[i].size()==0) continue;
        else
        {
            ll c=0;
            dfs(i,vis,num,c);
            cout<<c<<"\n";
            return;
        }
    } 
    cout <<"-1\n";

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

Problems suddenly got considerably hard starting from E. I breezed through A~D in 20 minutes, and spent 60 minutes to solve E.

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

How to solve G? I figured that the optimal route will pass through a floor f such that when considering only buildings with heights >=f, the source and destination would belong to same connected component.

To find this value of f for each query, I thought I could do a binary search but then maintaining the UnionFind structure would take O(N) per query, which is too slow. Another approach I thought of was to solve offline by adding each building one-by-one in decreasing order but then needing to check all Q queries after each addition is again too slow.

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

    consider small to large

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

    You can construct a minimum spanning tree and then use binary lifting to find the minimal edge weight on the path between nodes.

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

      I suppose the edge weights when constructing MST are simply the heights of building in each cell? Then I have a follow-up question:

      Let's say that there are two nodes A and B and minimum wt edge on the path A->B in MST is X. How do I know that there is not another path (not covered by the MST) that contains Y (>X) and also connect A and B? It's possible that going from source to dest using this Y edge would be cheaper, isn't it?

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

        You are correct about the edge weight being the building height. As for the second part, I incorrectly wrote minimum spanning tree when it should have been maximum spanning tree. Sorry for the confusion

»
14 months ago, hide # |
 
Vote: I like it -25 Vote: I do not like it

G is not good. Extremely straightforward idea, but pain in the ass to implement, not what I expect from atcoder contests. Rest of the problems were alright tbh.

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

Great contest. Could not solve E and F. Didn't even tried G but had fun. Problems are good. Thank you AtCoder team.

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

    Leaving Editorial of F for anyone like me out there cause it took me a 1 and a half days to solve it completely and most of the time on what resources to refer.

    1. Understand the ideas and terms re-routing, in-out dp and dp on trees.
    2. Do CSES trees section problems: Tree Diameter, Tree Distances I, Tree Distances II
    3. By now you will be able to solve it but here is more:
    Hints

    Here is the exact replica code. I hope it saves you a couple of hours.

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

Hi can anyone tell me what is wrong in my F submission

I am trying to only consider the nodes whose degree>=4 and for these trees trying to calculate the number of nodes i can pick up so that all the nodes have degree <=4

https://atcoder.jp/contests/abc394/submissions/63070024

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

Can someone from the future tell me how to solve E and F

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

    For E, the key idea is that if you have found the smallest palindromic path from i to j, then we will try to expand it on both sides and solve for other pairs. So, we can look for another pair (k, l) such that k connects to i and j connects to l using the same letter and now we have a path of 2 extra characters. We do this in increasing order of length of the found path and construct the answer using BFS.

    For F, we do a dp on tree. A node in Alkane can either have a parent and then 3 children or be root and have 4 children or be a leaf. For each node, we compute two things: 1. Largest subtree such that this is the root, i.e. has 4 children. -> most4[node] 2. Largest subtree where cur node is a child (can either supply 1 node acting as leaf or a subtree where cur node has 3 children) -> most3[node]

    Both of these are pretty simple to compute using dfs.

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

      Thanks, I really appreciate it but its been 4 years since i was an expert, can you please tell me in detail? I will be grateful, also what rated problems are these according to you?

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

my submission

can someone hacks me with my submission? I first find all points with at least 4 degrees and use union-find set to find the maximum number with 4 degrees in the subgraph and then calculate the ans.

#include<bits/stdc++.h>
using namespace std;
using u32 = unsigned;
using ll = long long;
using u64 = unsigned long long;
using ld = long double;

#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define fill(x, y) memset(x, y, sizeof(x))
#define si(x) ((int)(x).size())
#define dbg(x) cerr << #x << ": " << (x) << " "
#define debug(x) cerr << #x << ": " << (x) << endl

#define PI (ld)2 * acos(0.0)
#define MOD 998'244'353
#define MOD2 1'000'000'007

#define endl '\n'
#define YES cout << "YES" << endl; return
#define Yes cout << "Yes" << endl; return
#define yes cout << "yes" << endl; return
#define YE cout << "YES" << endl
#define Ye cout << "Yes" << endl
#define NO cout << "NO" << endl; return
#define No cout << "No" << endl; return
#define no cout << "no" << endl; return
#define IPSB cout << -1 << endl; return

const int inf = 0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fll;

#define int ll

class DSU {
  public:
	vector<int> parent, rank, size;

	DSU(int n) {
		parent.resize(n);
		rank.resize(n, 1);
		size.resize(n, 1);
		for (int i = 0; i < n; i++)
			parent[i] = i;
	}

	int find(int x) {
		if (parent[x] != x) {
			parent[x] = find(parent[x]);
		}
		return parent[x];
	}

	void unite(int x, int y) {
		int xr = find(x), yr = find(y);
		if (xr == yr)
			return;
		if (rank[xr] > rank[yr]) {
			parent[yr] = xr;
			size[xr] += size[yr];
		} else if (rank[xr] < rank[yr]) {
			parent[xr] = yr;
			size[yr] += size[xr];
		} else {
			parent[yr] = xr;
			rank[xr]++;
			size[xr] += size[yr];
		}
	}

	int get_size(int x) {
		return size[find(x)];
	}
};

void solve() {
	int N;
	cin >> N;

	vector<int> degree(N, 0);
	vector<pair<int, int>> edges;

	for (int i = 0; i < N - 1; i++) {
		int A, B;
		cin >> A >> B;
		A--;
		B--; // 0-based index
		edges.emplace_back(A, B);
		degree[A]++;
		degree[B]++;
	}

	vector<bool> is_high_degree(N, false);
	int flag = 0;
	for (int i = 0; i < N; i++) {
		if (degree[i] >= 4) {
			is_high_degree[i] = true;
			flag = 1;
		}
	}

	DSU dsu(N);
	bool has_cluster = false;

	for (auto [A, B] : edges) {
		if (is_high_degree[A] && is_high_degree[B]) {
			dsu.unite(A, B);
			has_cluster = true;
		}
	}

	if (!has_cluster) {
		if (flag == 0) {
			cout << -1 << endl;
		} else {
			cout << 5 << endl;
		}
	} else {
		int max_size = 1;
		map<int, int> component_size;
		for (int i = 0; i < N; i++) {
			if (is_high_degree[i]) {
				int root = dsu.find(i);
				component_size[root] = dsu.get_size(root);
				max_size = max(max_size, component_size[root]);
			}
		}
		int ans = max_size * 3 + 2;
		assert(ans <= N && max_size >= 2);
		cout << ans << endl;
	}

	return;
}

signed main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
/*
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	freopen("error.txt", "w", stderr);
	#endif
*/
	int ttest = 1;
//	cin >> ttest;
	while (ttest--) {
		solve();
	}
//	cerr << "Time:" << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << " ms" << endl;
	return 0;
}
»
14 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

I think problem C is harder than problem D. Problem D is very easy.

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

    C is even simpler than D if you see the simple trick: iterate the string in reverse order, then you can actually simply change all "WA" to "AC".

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

      I found that we can change all "WWW...A" to "ACCC...C". So in the end, I solve this problem.

      (Maybe my English isn't well...)

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

        My solution is the same as yours but this is not the best way to solve this problem. Just reverse the string is indeed a lot better.

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

Can someone please point out what's the problem with below logic of E.

Make a reversed graph of the original one. Run a multi-source BFS for each pair (i, j) on both G and reversed G. Move i to next_i following edge (i, next_i) in G and move j to next_j following edge (j, next_j) in reversed G when label of these two edges are the same. Once hitting i == j or C[i][j] != '-' means shortest path is found.