前几道题都比较简单, F 题感觉是字符串哈希,不过之前不了解没做出来,赛后看题解还可以用 Z Algorithm(扩展 KMP)。
比赛链接:https://atcoder.jp/contests/abc284/tasks
A - Sequence of Strings
题解
模拟。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include <bits/stdc++.h> using namespace std;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int n; cin >> n; vector<string> s (n) ; for (int i = 0 ; i < n; i++) { cin >> s[i]; } for (int i = n - 1 ; i >= 0 ; i--) { cout << s[i] << "\n" ; } return 0 ; }
B - Multi Test Cases
题解
模拟。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <bits/stdc++.h> using namespace std;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int t; cin >> t; while (t--) { int n; cin >> n; int odd = 0 ; for (int i = 0 ; i < n; i++) { int x; cin >> x; odd += (x & 1 ); } cout << odd << "\n" ; } return 0 ; }
C - Count Connected Components
题解
模拟。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <bits/stdc++.h> using namespace std;struct dsu { vector<int > fa, sz; dsu (int n) : fa (n), sz (n) { iota (fa.begin (), fa.end (), 0 ); fill (sz.begin (), sz.end (), 1 ); } int Find (int x) { return fa[x] == x ? x : fa[x] = Find (fa[x]); } void Union (int x, int y) { x = Find (x), y = Find (y); if (x == y) { return ; } if (sz[x] < sz[y]) { swap (x, y); } sz[x] += sz[y]; fa[y] = x; } int Size (int x) { return fa[x] == x ? sz[x] : sz[x] = sz[Find (x)]; } bool diff (int x, int y) { return Find (x) != Find (y); } }; int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int n, m; cin >> n >> m; dsu dsu (n) ; for (int i = 0 ; i < m; i++) { int u, v; cin >> u >> v; --u, --v; dsu.Union (u, v); } for (int i = 0 ; i < n; i++) { dsu.fa[i] = dsu.Find (i); } cout << set (dsu.fa.begin (), dsu.fa.end ()).size () << "\n" ; return 0 ; }
D - Happy New Year 2023
题解
m i n ( p , q ) ≤ n 3 min(p, q) \le \sqrt[3]{n} m i n ( p , q ) ≤ 3 n ,当 n = 9 × 1 0 18 n = 9 \times 10^{18} n = 9 × 1 0 1 8 时, m i n ( p , q ) ≤ n 3 < 3 × 1 0 6 min(p, q) \le \sqrt[3]{n} \lt 3 \times 10^6 m i n ( p , q ) ≤ 3 n < 3 × 1 0 6 ,所以筛出 3 × 1 0 6 3 \times 10^6 3 × 1 0 6 内的素数,枚举并讨论是 p p p 或 q q q 的两种情况即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <bits/stdc++.h> using namespace std;constexpr int N = 3e6 ;vector<bool > is_prime (N, true ) ;void Init () { is_prime[0 ] = is_prime[1 ] = false ; for (int i = 2 ; i < N; i++) { if (not is_prime[i]) { continue ; } for (int j = i + i; j < N; j += i) { is_prime[j] = false ; } } } int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); Init (); vector<long long > primes; for (int i = 2 ; i < N; i++) { if (is_prime[i]) { primes.push_back (i); } } int t; cin >> t; while (t--) { long long n; cin >> n; long long p = -1 , q = -1 ; for (auto x : primes) { if (n % (x * x) == 0 ) { p = x, q = n / (x * x); } else if (n % x == 0 ) { p = sqrt (n / x), q = x; } } cout << p << ' ' << q << "\n" ; } return 0 ; }
E - Count Simple Paths
题解
输出 m i n ( k , 1 0 6 ) min(k, 10^6) m i n ( k , 1 0 6 ) ,所以 dfs 模拟即可,加一个标记数组防止访问环。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 #include <bits/stdc++.h> using namespace std;int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int n, m; cin >> n >> m; vector<vector<int >> G (n); for (int i = 0 ; i < m; i++) { int u, v; cin >> u >> v; --u, --v; G[u].push_back (v); G[v].push_back (u); } int ans = 0 ; vector<bool > vis (n) ; function<void (int , int )> dfs = [&](int u, int p) { if (ans == 1E6 ) { return ; } ans += 1 ; for (auto v : G[u]) { if (v != p and not vis[v]) { vis[v] = true ; dfs (v, u); vis[v] = false ; } } }; vis[0 ] = true ; dfs (0 , -1 ); vis[0 ] = false ; cout << ans << "\n" ; return 0 ; }
F - ABCBAC
题解
枚举 + 字符串哈希,由于中间有一个原串的反向串,所以需要正反向建立两个哈希。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 #include <bits/stdc++.h> using namespace std;const int L = 2e6 + 5 ;const int HASH_CNT = 2 ;int hashBase[HASH_CNT] = {29 , 31 }; int hashMod[HASH_CNT] = {int (1e9 + 9 ), 998244353 }; struct StringWithHash { char s[L]; int ls; int hsh[HASH_CNT][L]; int pwMod[HASH_CNT][L]; void init () { ls = 0 ; for (int i = 0 ; i < HASH_CNT; ++i) { hsh[i][0 ] = 0 ; pwMod[i][0 ] = 1 ; } } StringWithHash () { init (); } void extend (char c) { s[++ls] = c; for (int i = 0 ; i < HASH_CNT; ++i) { pwMod[i][ls] = 1ll * pwMod[i][ls - 1 ] * hashBase[i] % hashMod[i]; hsh[i][ls] = (1ll * hsh[i][ls - 1 ] * hashBase[i] + c) % hashMod[i]; } } vector<int > getHash (int l, int r) { vector<int > res (HASH_CNT, 0 ) ; for (int i = 0 ; i < HASH_CNT; ++i) { int t = (hsh[i][r] - 1ll * hsh[i][l - 1 ] * pwMod[i][r - l + 1 ]) % hashMod[i]; t = (t + hashMod[i]) % hashMod[i]; res[i] = t; } return res; } }; StringWithHash H1, H2; int main () { ios::sync_with_stdio (false ); cin.tie (nullptr ); int n; cin >> n; n *= 2 ; string s; cin >> s; string t = string (s.rbegin (), s.rend ()); for (int i = 0 ; i < n; i++) { H1. extend (s[i]); H2. extend (t[i]); } int ans = -1 ; int l = 1 , r = n / 2 ; while (r <= n) { if ((l - 1 < 1 or H1. getHash (1 , l - 1 ) == H2. getHash (n - r + 1 , n - r + 1 + (l - 2 ))) and (r + 1 > n or H1. getHash (r + 1 , n) == H2. getHash (n - r + 1 + (l - 1 ), n - r + 1 + (l - 1 ) + (n - r - 1 )))) { ans = l - 1 ; break ; } l += 1 , r += 1 ; } if (ans == -1 ) { cout << -1 << "\n" ; } else { cout << t.substr (n - r, n / 2 ) << "\n" ; cout << ans << "\n" ; } return 0 ; }