A. Strong Password
Problem Statement
Monocarp’s current password on Codeforces is a string s s s, consisting of lowercase Latin letters. Monocarp thinks that his current password is too weak, so he wants to insert exactly one lowercase Latin letter into the password to make it stronger. Monocarp can choose any letter and insert it anywhere, even before the first character or after the last character.
Monocarp thinks that the password’s strength is proportional to the time it takes him to type the password. The time it takes to type the password is calculated as follows:
- the time to type the first character is 2 2 2 seconds;
- for each character other than the first, the time it takes to type it is 1 1 1 second if it is the same as the previous character, or 2 2 2 seconds otherwise.
For example, the time it takes to type the password abacaba is 14 14 14; the time it takes to type the password a is 2 2 2; the time it takes to type the password aaabacc is 11 11 11.
You have to help Monocarp — insert a lowercase Latin letter into his password so that the resulting password takes the maximum possible amount of time to type.
Input
The first line contains one integer t t t ( 1 ≤ t ≤ 1000 1 \le t \le 1000 1≤t≤1000) — the number of test cases.
Each test case consists of one line containing the string s s s ( 1 ≤ ∣ s ∣ ≤ 10 1 \le |s| \le 10 1≤∣s∣≤10), consisting of lowercase Latin letters.
Output
For each test case, print one line containing the new password — a string which can be obtained from s s s by inserting one lowercase Latin letter. The string you print should have the maximum possible required time to type it. If there are multiple answers, print any of them.
Example
input |
---|
4 |
a |
aaa |
abb |
password |
output |
---|
wa |
aada |
abcb |
pastsword |
Solution
具体见文后视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
void solve() {
string s;
cin >> s;
for (int i = 1; i < s.size(); i ++)
if (s[i] == s[i - 1]) {
char ins;
if (s[i] == 'z') ins = 'a';
else ins = s[i] + 1;
for (int j = 0; j < i; j ++) cout << s[j];
cout << ins;
for (int j = i; j < s.size(); j ++) cout << s[j];
cout << endl;
return;
}
char ins;
if (s.back() == 'z') ins = 'a';
else ins = s.back() + 1;
cout << s << ins << endl;
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int dt;
cin >> dt;
while (dt --)
solve();
return 0;
}
B. Make Three Regions
Problem Statement
There is a grid, consisting of 2 2 2 rows and n n n columns. Each cell of the grid is either free or blocked.
A free cell y y y is reachable from a free cell x x x if at least one of these conditions holds:
- x x x and y y y share a side;
- there exists a free cell z z z such that z z z is reachable from x x x and y y y is reachable from z z z.
A connected region is a set of free cells of the grid such that all cells in it are reachable from one another, but adding any other free cell to the set violates this rule.
For example, consider the following layout, where white cells are free, and dark grey cells are blocked:
There are
3
3
3 regions in it, denoted with red, green and blue color respectively:
The given grid contains at most 1 1 1 connected region. Your task is to calculate the number of free cells meeting the following constraint:
- if this cell is blocked, the number of connected regions becomes exactly 3 3 3.
Input
The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1≤t≤104) — the number of test cases.
The first line of each test case contains a single integer n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \le n \le 2 \cdot 10^5 1≤n≤2⋅105) — the number of columns.
The i i i-th of the next two lines contains a description of the i i i-th row of the grid — the string s i s_i si, consisting of n n n characters. Each character is either . (denoting a free cell) or x (denoting a blocked cell).
Additional constraint on the input:
- the given grid contains at most 1 1 1 connected region;
- the sum of n n n over all test cases doesn’t exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.
Output
For each test case, print a single integer — the number of cells such that the number of connected regions becomes 3 3 3 if this cell is blocked.
Example
input |
---|
4 |
8 |
…x |
.x.xx… |
2 |
… |
… |
3 |
xxx |
xxx |
9 |
…x.x.x.x |
x…x |
output |
---|
1 |
0 |
0 |
2 |
Note
In the first test case, if the cell ( 1 , 3 ) (1, 3) (1,3) is blocked, the number of connected regions becomes 3 3 3 (as shown in the picture from the statement).
Solution
具体见文后视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
void solve() {
int n;
string s[2];
cin >> n >> s[0] >> s[1];
int res = 0;
for (int i = 0; i < 2; i ++)
for (int j = 1; j < n - 1; j ++)
if (s[i][j] == '.' && s[i][j - 1] != 'x' && s[i][j + 1] != 'x' && s[i ^ 1][j] == '.' && s[i ^ 1][j - 1] == 'x' && s[i ^ 1][j + 1] == 'x')
res ++;
cout << res << endl;
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int dt;
cin >> dt;
while (dt --)
solve();
return 0;
}
C. Even Positions
Problem Statement
Monocarp had a regular bracket sequence s s s of length n n n ( n n n is even). He even came up with his own way to calculate its cost.
He knows that in a regular bracket sequence (RBS), each opening bracket is paired up with the corresponding closing bracket. So he decided to calculate the cost of RBS as the sum of distances between pairs of corresponding bracket pairs.
For example, let’s look at RBS (())(). It has three pairs of brackets:
- (__)__: the distance between brackets at position 1 1 1 and at 4 4 4 is 4 − 1 = 3 4 - 1 = 3 4−1=3;
- _()___: the distance is 3 − 2 = 1 3 - 2 = 1 3−2=1;
- ____(): the distance is 6 − 5 = 1 6 - 5 = 1 6−5=1.
So the cost of (())() is 3 + 1 + 1 = 5 3 + 1 + 1 = 5 3+1+1=5.
Unfortunately, due to data corruption, Monocarp lost all characters on odd positions s 1 , s 3 , … , s n − 1 s_1, s_3, \dots, s_{n-1} s1,s3,…,sn−1. Only characters on even positions ( s 2 , s 4 , … , s n s_2, s_4, \dots, s_{n} s2,s4,…,sn) remain. For example, (())() turned to _(_)_).
Monocarp wants to restore his RBS by placing brackets on the odd positions. But since the restored RBS may not be unique, he wants to choose one with minimum cost. It’s too hard to do for Monocarp alone, so can you help him?
Reminder: A regular bracket sequence is a string consisting of only brackets, such that this sequence, when inserted 1-s and +-s, gives a valid mathematical expression. For example, (), (()) or (()())() are RBS, while ), ()( or ())(() are not.
Input
The first line contains a single integer t t t ( 1 ≤ t ≤ 5000 1 \le t \le 5000 1≤t≤5000) — the number of test cases. Next t t t cases follow.
The first line of each test case contains a single integer n n n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 2 \le n \le 2 \cdot 10^5 2≤n≤2⋅105; n n n is even) — the length of string s s s.
The second line of each test case contains a string s s s of length n n n, where all characters on the odd positions are ‘_’ and all characters on the even positions are either ‘(’ or ‘)’.
Additional constraints:
- s s s can be restored to at least one regular bracket sequence;
- the total sum of n n n over all test cases doesn’t exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.
Output
For each test case, print one integer — the minimum cost of the regular bracket sequence that can be obtained from s s s by replacing ‘_’-s with brackets.
Example
input |
---|
4 |
6 |
()_) |
2 |
_) |
8 |
)))) |
8 |
()() |
output |
---|
5 |
1 |
4 |
8 |
Note
In the first test case, it’s optimal to make s s s equal to (())(). The cost of s s s will be equal to 3 + 1 + 1 = 5 3 + 1 + 1 = 5 3+1+1=5.
In the second test case, the only option is to make s s s equal to () with cost 1 1 1.
In the third test case, the only possible RBS is ()()()() with cost 1 + 1 + 1 + 1 = 4 1 + 1 + 1 + 1 = 4 1+1+1+1=4.
In the fourth test case, it’s optimal to make s s s equal to (())(()) with cost 3 + 1 + 3 + 1 = 8 3 + 1 + 3 + 1 = 8 3+1+3+1=8.
Solution
具体见文后视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
void solve() {
int n;
string s;
cin >> n >> s;
int no = 0;
for (int i = 0; i < n; i ++) {
if (i % 2 == 0) {
if (!no) s[i] = '(', no ++;
else s[i] = ')', no --;
} else {
if (s[i] == '(') no ++;
else no --;
}
}
stack<int> stk;
int res = 0;
for (int i = 0; i < n; i ++)
if (s[i] == '(') stk.push(i);
else res += i - stk.top(), stk.pop();
cout << res << endl;
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int dt;
cin >> dt;
while (dt --)
solve();
return 0;
}
D. Maximize the Root
Problem Statement
You are given a rooted tree, consisting of n n n vertices. The vertices in the tree are numbered from 1 1 1 to n n n, and the root is the vertex 1 1 1. The value a i a_i ai is written at the i i i-th vertex.
You can perform the following operation any number of times (possibly zero): choose a vertex v v v which has at least one child; increase a v a_v av by 1 1 1; and decrease a u a_u au by 1 1 1 for all vertices u u u that are in the subtree of v v v (except v v v itself). However, after each operation, the values on all vertices should be non-negative.
Your task is to calculate the maximum possible value written at the root using the aforementioned operation.
Input
The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1≤t≤104) — the number of test cases.
The first line of each test case contains a single integer n n n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 2 \le n \le 2 \cdot 10^5 2≤n≤2⋅105) — the number of vertices in the tree.
The second line contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an ( 0 ≤ a i ≤ 1 0 9 0 \le a_i \le 10^9 0≤ai≤109) — the initial values written at vertices.
The third line contains n − 1 n-1 n−1 integers p 2 , p 3 , … , p n p_2, p_3, \dots, p_n p2,p3,…,pn ( 1 ≤ p i ≤ n 1 \le p_i \le n 1≤pi≤n), where p i p_i pi is the parent of the i i i-th vertex in the tree. Vertex 1 1 1 is the root.
Additional constraint on the input: the sum of n n n over all test cases doesn’t exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.
Output
For each test case, print a single integer — the maximum possible value written at the root using the aforementioned operation.
Example
input |
---|
3 |
4 |
0 1 0 2 |
1 1 3 |
2 |
3 0 |
1 |
5 |
2 5 3 9 6 |
3 1 5 2 |
output |
---|
1 |
3 |
6 |
Note
In the first test case, the following sequence of operations is possible:
- perform the operation on v = 3 v=3 v=3, then the values on the vertices will be [ 0 , 1 , 1 , 1 ] [0, 1, 1, 1] [0,1,1,1];
- perform the operation on v = 1 v=1 v=1, then the values on the vertices will be [ 1 , 0 , 0 , 0 ] [1, 0, 0, 0] [1,0,0,0].
Solution
具体见文后视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define int long long
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 2e5 + 10, inf = 1e18;
int n;
int a[N], val[N];
std::vector<int> g[N];
void dfs(int u) {
val[u] = a[u];
int mn = inf;
for (auto v : g[u]) dfs(v), mn = min(mn, val[v]);
if (mn != inf) {
if (val[u] > mn) val[u] = mn;
else val[u] = val[u] + mn >> 1;
}
}
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 2; i <= n; i ++) {
int p; cin >> p;
g[p].push_back(i);
}
dfs(1);
int res = inf;
for (auto v : g[1]) res = min(res, val[v]);
cout << res + a[1] << endl;
for (int i = 1; i <= n; i ++) g[i].clear(), val[i] = 0;
}
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int dt;
cin >> dt;
while (dt --)
solve();
return 0;
}
E. Level Up
Problem Statement
Monocarp is playing a computer game. He starts the game being level 1 1 1. He is about to fight n n n monsters, in order from 1 1 1 to n n n. The level of the i i i-th monster is a i a_i ai.
For each monster in the given order, Monocarp’s encounter goes as follows:
- if Monocarp’s level is strictly higher than the monster’s level, the monster flees (runs away);
- otherwise, Monocarp fights the monster.
After every k k k-th fight with a monster (fleeing monsters do not count), Monocarp’s level increases by 1 1 1. So, his level becomes 2 2 2 after k k k monsters he fights, 3 3 3 after 2 k 2k 2k monsters, 4 4 4 after 3 k 3k 3k monsters, and so on.
You need to process q q q queries of the following form:
- i x i~x i x: will Monocarp fight the i i i-th monster (or will this monster flee) if the parameter k k k is equal to x x x?
Input
The first line contains two integers n n n and q q q ( 1 ≤ n , q ≤ 2 ⋅ 1 0 5 1 \le n, q \le 2 \cdot 10^5 1≤n,q≤2⋅105) — the number of monsters and the number of queries.
The second line contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an ( 1 ≤ a i ≤ 2 ⋅ 1 0 5 1 \le a_i \le 2 \cdot 10^5 1≤ai≤2⋅105) — the levels of the monsters.
In the j j j-th of the following q q q lines, two integers i i i and x x x ( 1 ≤ i , x ≤ n 1 \le i, x \le n 1≤i,x≤n) — the index of the monster and the number of fights required for a level up in the j j j-th query.
Output
For each query, output “YES”, if Monocarp will fight the i i i-th monster in this query, and “NO”, if the i i i-th monster flees.
Example
input |
---|
4 16 |
2 1 2 1 |
1 1 |
2 1 |
3 1 |
4 1 |
1 2 |
2 2 |
3 2 |
4 2 |
1 3 |
2 3 |
3 3 |
4 3 |
1 4 |
2 4 |
3 4 |
4 4 |
output |
---|
YES |
NO |
YES |
NO |
YES |
YES |
YES |
NO |
YES |
YES |
YES |
NO |
YES |
YES |
YES |
YES |
input |
---|
7 15 |
1 1 2 1 1 1 1 |
5 3 |
2 2 |
2 2 |
1 6 |
5 1 |
5 5 |
7 7 |
3 5 |
7 4 |
4 3 |
2 5 |
1 2 |
5 6 |
4 1 |
6 1 |
output |
---|
NO |
YES |
YES |
YES |
NO |
YES |
YES |
YES |
NO |
NO |
YES |
YES |
YES |
NO |
NO |
Solution
具体见文后视频。
Code
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int N = 2e5 + 10, B = 1800;
int n, q;
int a[N], cnt[N / B + 10][N];
bool res[N];
std::vector<PII> qry[B + 5];
signed main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> n >> q;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= N / B + 5; i ++)
for (int j = 1; j <= n; j ++)
cnt[i][j] = cnt[i][j - 1] + (a[j] >= i);
for (int _ = 1; _ <= q; _ ++) {
int x, k;
cin >> x >> k;
if (k <= B) {
qry[k].push_back({x, _});
} else {
int p = 1;
for (int i = 1; i <= N / B + 5; i ++) {
int lo = p, ro = x - 1, ok = -1;
while (lo <= ro) {
int mid = lo + ro >> 1;
if (cnt[i][mid] - cnt[i][p - 1] >= k) ro = mid - 1, ok = mid;
else lo = mid + 1;
}
if (ok == -1) {
if (a[x] >= i) res[_] = true;
else res[_] = false;
break;
}
p = ok + 1;
}
}
}
for (int i = 1; i <= min(B, n); i ++) {
sort(qry[i].begin(), qry[i].end());
int tot = 0, lvl = 1;
for (int j = 1, k = 0; j <= n; j ++) {
if (tot == i) lvl ++, tot = 0;
while (k < qry[i].size() && j == qry[i][k].fi) {
if (a[j] >= lvl) res[qry[i][k].se] = true;
else res[qry[i][k].se] = false;
k ++;
}
if (a[j] >= lvl) tot ++;
}
}
for (int i = 1; i <= q; i ++)
if (res[i]) cout << "YES" << endl;
else cout << "NO" << endl;
return 0;
}
视频讲解
Educational Codeforces Round 168 (Rated for Div. 2)(A ~ E 题讲解)
最后祝大家早日