TEST 11
A. 拆盒子
- 贪心贪过去就好了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15signed main() {
IOS;
string s;
cin >> s;
int len = s.size();
int sum = 0;
for (int i = 0; i < len; i++) {
if (s[i] == '(') sum++;
else if(s[i] == ')') sum--;
else break;
}
cout << sum << endl;
return 0;
}
B. 数组调整
- 枚举最小值,算最大值就好了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21signed main() {
IOS;
int n;
cin >> n;
vector<int> v(n);
for (int i = 0; i < n; i++) {
cin >> v[i];
}
ll ans = 1e18;
for (int i = 0; i <= 100; i++) {
ll res = 0;
for (int j = 0; j < n; j++) {
int x = v[j];
if (x > i + 17) res += (x - i - 17) * (x - i - 17);
else if (x < i) res += (i - x) * (i - x);
}
ans = min(ans, res);
}
cout << ans << endl;
return 0;
}
C. 密码
- 递归搜索
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16int dfs(string s) {
if ((s.size() % 2) == 0) return 1;
int m = s.size() >> 1;
int sumL = (s.substr(1, m) == s.substr(m + 1, m)) + (s.substr(0, m) == s.substr(m + 1, m));
int sumR = (s.substr(0, m) == s.substr(m + 1, m)) + (s.substr(0, m) == s.substr(m, m));
return (sumL ? dfs(s.substr(0, m + 1)) * sumL : 0) + (sumR ? dfs(s.substr(m, m + 1)) * sumR : 0) + 1;
}
signed main() {
IOS;
string s;
cin >> s;
cout << dfs(s) - 1 << endl;
return 0;
}
D. 序列操作
- 从前往后贪心就好了,然后加一个特判
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20signed main() {
IOS;
int n;
cin >> n;
vector<int> a(n + 1);
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
ll ans = 0;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
a[i] -= x;
ans += max(0, a[i] - a[i - 1]);
}
ans += max(0, -1 * a[n]);
cout << ans << endl;
return 0;
}
E. 交错序列
1 | int n, k; |
F. 动态建边
- 树上前缀和 + 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
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
int n, m, w[MAX];
int tot, L[MAX], R[MAX], d[MAX], dis[MAX], f[MAX][20];
vector<int> G[MAX];
struct dat {
string s;
int x, y, ans;
} a[MAX];
int F[MAX];
int find(int x) {
if (x == F[x]) {
return x;
}
else {
return F[x] = find(F[x]);
}
}
int c[MAX];
void add(int x, int k) {
for (; x <= n; x += (x & (-x)))
c[x] += k;
}
int ask(int x) {
int ans = 0;
for (; x; x -= (x & (-x)))
ans += c[x];
return ans;
}
void dfs(int x, int fa) {
L[x] = ++tot;
d[x] = d[fa] + 1;
f[x][0] = fa;
dis[x] = dis[fa] + w[x];
add(L[x], dis[x]), add(L[x] + 1, -dis[x]);
for (int i = 1; i <= 18; i++) {
f[x][i] = f[f[x][i - 1]][i - 1];
}
for (int y : G[x]) {
if (y == fa) {
continue;
}
dfs(y, x);
}
R[x] = tot;
}
int LCA(int x, int y) {
if (d[x] < d[y]) {
swap(x, y);
}
for (int i = 18; ~i; i--) {
if (d[f[x][i]] >= d[y])
x = f[x][i];
}
if(x == y)
return x;
for (int i = 18; ~i; i--) {
if(f[x][i] == f[y][i])
continue;
x = f[x][i], y = f[y][i];
}
return f[x][0];
}
signed main() {
IOS;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> w[i];
F[i] = i;
}
cin >> m;
for (int i = 1, x, y, ans; i <= m; i++) {
string s;
cin >> s >> x >> y;
ans = 0;
if (s == "bridge") {
int fx = find(x), fy = find(y);
if (fx != fy) {
ans = 1;
F[fy] = fx;
G[x].push_back(y), G[y].push_back(x);
}
}
if (s == "excursion") {
int fx = find(x), fy = find(y);
if (fx != fy)
ans = 1;
}
a[i] = {s, x, y, ans};
}
for (int i = 1; i <= n; i++) {
if (!L[i])
dfs(i, 0);
}
for (int i = 1; i <= m; i++) {
//auto [s, x, y, ans] = a[i];
string s = a[i].s;
int x = a[i].x, y = a[i].y, ans = a[i].ans;
if (s == "bridge")
{
cout << (ans ? "yes" : "no") << endl;
}
else if (s == "penguins")
{
add(L[x], y - w[x]);
add(R[x] + 1, w[x] - y);
w[x] = y;
}
else {
//cout << ans << ' ';
if (ans) {
cout << "impossible" << endl;
continue;
}
//cout << ans << ' ';
int t = LCA(x, y);
cout << ask(L[x]) + ask(L[y]) - ask(L[t]) - ask(L[f[t][0]]) << endl;
}
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ysmmm的快乐小屋!