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

Автор atcoder_official, история, 19 месяцев назад, По-английски

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

We are looking forward to your participation!

  • Проголосовать: нравится
  • +66
  • Проголосовать: не нравится

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

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

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

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

upd: this round is worse than last one again.

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

Wish no more AI Best Contest plz.

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

painful

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

Why ABC G. is so hard?

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

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).

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

Why this gives TLE for E in 2 test cases ?

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

How to solve E?

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

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;
}

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

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

My submission

Thanks in advance

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

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

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

Why is this wrong for F Alkane?

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

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

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

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";

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

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

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

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.

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

    consider small to large

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

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

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

      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?

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

        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

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

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.

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

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

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

    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.

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

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

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

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

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

    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.

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

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;
}
»
19 месяцев назад, скрыть # |
 
Проголосовать: нравится 0 Проголосовать: не нравится

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

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

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.

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

I think ABC is easier and easier.