AtCoder Beginner Contest 284【A - F】

前几道题都比较简单, 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

题解

min(p,q)n3min(p, q) \le \sqrt[3]{n} ,当 n=9×1018n = 9 \times 10^{18} 时, min(p,q)n3<3×106min(p, q) \le \sqrt[3]{n} \lt 3 \times 10^6 ,所以筛出 3×1063 \times 10^6 内的素数,枚举并讨论是 ppqq 的两种情况即可。

代码

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

题解

输出 min(k,106)min(k, 10^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}; // {13331, 23333}
int hashMod[HASH_CNT] = {int(1e9 + 9), 998244353}; // {1e9 + 7, 1e9 + 9}

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]; // 得到b^ls
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;
}

AtCoder Beginner Contest 284【A - F】

https://www.kanoon.cn/2023/01/08/ABC 284/

作者

Kanoon

发布于

2023-01-08

更新于

2023-01-11

许可协议

评论