Solution to AtCoder Beginner Contest 446
D - Max Straight
This problem can be solved efficient using a hash map. Initially, I overcomplicated it by thinking about sorting and finding the longest increasing subsequence. However, a simple approach using a map workss perfectly.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
unordered_map<int, int> freq;
int result = 0;
for (int i = 0; i < n; ++i) {
int value;
cin >> value;
freq[value] = max(freq[value], freq[value - 1] + 1);
result = max(result, freq[value]);
}
cout << result << endl;
return 0;
}
E - Multiple-Free Sequences
This is a mathematical problem involving cycle detection in modular arithmetic. A depth-first search (DFS) is used to traverse sequences and determine which pairs are valid.
int answer = 0;
bool visited[100005][100005];
bool invalid[100005][100005];
void dfs(int x, int y) {
if (x == 0 || y == 0) {
invalid[x][y] = true;
return;
}
if (visited[x][y]) return;
visited[x][y] = true;
int next_x = y % m;
int next_y = (a * y + b * x) % m;
dfs(next_x, next_y);
invalid[x][y] = invalid[next_x][next_y];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> m >> a >> b;
for (int x = 1; x < m; ++x) {
for (int y = 1; y < m; ++y) {
if (!visited[x][y]) dfs(x, y);
answer += !invalid[x][y];
}
}
cout << answer;
return 0;
}
F - Reachable Set 2
This problem involves determining reachabliity in a directed graph using shortest path algorithms and then calculating how many nodes can be removed while maintaining reachability. The key steps involve running a modified Dijkstra’s algorithm and tracking prefix maximums.
#define N 100005
#define pii pair<int, int>
int n, m;
vector<int> adj[N];
priority_queue<pii, vector<pii>, greater<pii> > pq;
bool visited[N];
int distance[N];
int prefix_max[N];
map<pii, int> edge_map;
bool marked[N];
void dijkstra() {
memset(distance, 0x3f, sizeof distance);
distance[1] = 1;
pq.push({1, 1});
while (!pq.empty()) {
int u = pq.top().second;
pq.pop();
if (visited[u]) continue;
visited[u] = true;
for (auto v : adj[u]) {
if (distance[v] > max(distance[u], v)) {
distance[v] = max(distance[u], v);
pq.push({distance[v], v});
}
}
}
}
void solve() {
cin >> n >> m;
int u, v;
for (int i = 1; i <= m; ++i) {
cin >> u >> v;
if (u == v) continue;
if (edge_map[{u, v}]) continue;
adj[u].push_back(v);
edge_map[{u, v}] = 1;
}
dijkstra();
for (int i = 1; i <= n; ++i) {
prefix_max[i] = max(prefix_max[i - 1], distance[i]);
}
int count = 0;
for (int i = 1; i <= n; ++i) {
bool flag = false;
for (auto node : adj[i]) {
if (!marked[node]) {
marked[node] = true;
count++;
}
}
if (marked[i]) count--;
marked[i] = true;
if (prefix_max[i] > i) cout << -1 << endl;
else cout << count << endl;
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1;
while (T--) {
solve();
}
return 0;
}