A. Make it White
You have a horizontal strip of n n n cells. Each cell is either white or black.
You can choose a continuous segment of cells once and paint them all white. After this action, all the black cells in this segment will become white, and the white ones will remain white.
What is the minimum length of the segment that needs to be painted white in order for all n n n cells to become white?
Input
The first line of the input 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 descriptions of the test cases follow.
The first line of each test case contains a single integer n n n ( 1 ≤ n ≤ 10 1 \le n \le 10 1≤n≤10) — the length of the strip.
The second line of each test case contains a string s s s, consisting of n n n characters, each of which is either ‘W’ or ‘B’. The symbol ‘W’ denotes a white cell, and ‘B’ — a black one. It is guaranteed that at least one cell of the given strip is black.
Output
For each test case, output a single number — the minimum length of a continuous segment of cells that needs to be painted white in order for the entire strip to become white.
Example
input
8
6
WBBWBW
1
B
2
WB
3
BBW
4
BWWB
6
BWBWWB
6
WWBBWB
9
WBWBWWWBW
output
4
1
1
2
4
6
4
7
Note
In the first test case of the example for the strip “WBBWBW”, the minimum length of the segment to be repainted white is 4 4 4. It is necessary to repaint to white the segment from the 2 2 2-nd to the 5 5 5-th cell (the cells are numbered from 1 1 1 from left to right).
Tutorial
由于只能选择一次连续的单元格段,所以必须一次包含所有的 B
,此时记录最左边的 B
的位置和最右边 B
的位置即可,时间复杂度
O
(
n
)
O(n)
O(n)
Solution
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
void solve() {
int n;
string s;
cin >> n >> s;
int mn = INF, mx = 0;
for (int i = 0; i < n; ++i) {
if (s[i] == 'B') {
mn = min(mn, i);
mx = max(mx, i);
}
}
cout << mx - mn + 1 << endl;
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
cout << fixed << setprecision(15);
int Test; cin >> Test; while (Test--)
solve();
return 0;
}
B. Following the String
Polycarp lost the string s s s of length n n n consisting of lowercase Latin letters, but he still has its trace.
The trace of the string s s s is an array a a a of n n n integers, where a i a_i ai is the number of such indices j j j ( j < i j < i j<i) that s i = s j s_i=s_j si=sj. For example, the trace of the string abracadabra is the array [ 0 , 0 , 0 , 1 , 0 , 2 , 0 , 3 , 1 , 1 , 4 0, 0, 0, 1, 0, 2, 0, 3, 1, 1, 4 0,0,0,1,0,2,0,3,1,1,4].
Given a trace of a string, find any string s s s from which it could have been obtained. The string s s s should consist only of lowercase Latin letters a-z.
Input
The first line of the input 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. Then the descriptions of the test cases follow.
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 length of the lost string.
The second line of each test case contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an ( 0 ≤ a i < n 0 \le a_i < n 0≤ai<n) — the trace of the string. It is guaranteed that for the given trace, there exists a suitable string s s s.
It is guaranteed that the sum of n n n over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.
Output
For each test case, output a string s s s that corresponds to the given trace. If there are multiple such strings s s s, then output any of them.
The string s s s should consist of lowercase Latin letters a-z.
It is guaranteed that for each test case, a valid answer exists.
Example
input
5
11
0 0 0 1 0 2 0 3 1 1 4
10
0 0 0 0 0 1 0 1 1 0
1
0
8
0 1 2 3 4 5 6 7
8
0 0 0 0 0 0 0 0
output
abracadabra
codeforces
a
aaaaaaaa
dijkstra
Tutorial
题目已经表明必定存在有效的答案了,所以只需要在每个位置遍历 a
~ z
,找出符合出现次数要求的字母加到答案中即可,时间复杂度
O
(
n
)
O(n)
O(n)
Solution
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
void solve() {
int n;
string ans = "";
cin >> n;
vector<int> a(n);
map<char, int> mp;
for (int i = 0; i < n; ++i) {
int x;
cin >> x;
for (char c = 'a'; c <= 'z'; ++c) {
if (mp[c] == x) {
ans += c;
++mp[c];
break;
}
}
}
cout << ans << endl;
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
cout << fixed << setprecision(15);
int Test; cin >> Test; while (Test--)
solve();
return 0;
}
C. Choose the Different Ones!
Given an array a a a of n n n integers, an array b b b of m m m integers, and an even number k k k.
Your task is to determine whether it is possible to choose exactly k 2 \frac{k}{2} 2k elements from both arrays in such a way that among the chosen elements, every integer from 1 1 1 to k k k is included.
For example:
- If a = [ 2 , 3 , 8 , 5 , 6 , 5 ] a=[2, 3, 8, 5, 6, 5] a=[2,3,8,5,6,5], b = [ 1 , 3 , 4 , 10 , 5 ] b=[1, 3, 4, 10, 5] b=[1,3,4,10,5], k = 6 k=6 k=6, then it is possible to choose elements with values 2 , 3 , 6 2, 3, 6 2,3,6 from array a a a and elements with values 1 , 4 , 5 1, 4, 5 1,4,5 from array b b b. In this case, all numbers from 1 1 1 to k = 6 k=6 k=6 will be included among the chosen elements.
- If a = [ 2 , 3 , 4 , 5 , 6 , 5 ] a=[2, 3, 4, 5, 6, 5] a=[2,3,4,5,6,5], b = [ 1 , 3 , 8 , 10 , 3 ] b=[1, 3, 8, 10, 3] b=[1,3,8,10,3], k = 6 k=6 k=6, then it is not possible to choose elements in the required way.
Note that you are not required to find a way to choose the elements — your program should only check whether it is possible to choose the elements in the required way.
Input
The first line of the input 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 descriptions of the test cases follow.
The first line of each test case contains three integers n n n, m m m, and k k k ( 1 ≤ n , m ≤ 2 ⋅ 1 0 5 1 \le n, m \le 2\cdot10^5 1≤n,m≤2⋅105, 2 ≤ k ≤ 2 ⋅ min ( n , m ) 2 \le k \le 2 \cdot \min(n, m) 2≤k≤2⋅min(n,m), k k k is even) — the length of array a a a, the length of array b b b, and the number of elements to be chosen, respectively.
The second line of each test case contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an ( 1 ≤ a i ≤ 1 0 6 1 \le a_i \le 10^6 1≤ai≤106) — the elements of array a a a.
The third line of each test case contains m m m integers b 1 , b 2 , … , b m b_1, b_2, \dots, b_m b1,b2,…,bm ( 1 ≤ b j ≤ 1 0 6 1 \le b_j \le 10^6 1≤bj≤106) — the elements of array b b b.
It is guaranteed that the sum of values n n n and m m m over all test cases in a test does not exceed 4 ⋅ 1 0 5 4 \cdot 10^5 4⋅105.
Output
Output t t t lines, each of which is the answer to the corresponding test case. As the answer, output “YES” if it is possible to choose k 2 \frac{k}{2} 2k numbers from each array in such a way that among the chosen elements, every integer from 1 1 1 to k k k is included. Otherwise, output “NO”.
You can output each letter in any case (lowercase or uppercase). For example, the strings “yEs”, “yes”, “Yes”, and “YES” will be accepted as a positive answer.
Example
input
6
6 5 6
2 3 8 5 6 5
1 3 4 10 5
6 5 6
2 3 4 5 6 5
1 3 8 10 3
3 3 4
1 3 5
2 4 6
2 5 4
1 4
7 3 4 4 2
1 4 2
2
6 4 4 2
1 5 2
3
2 2 1 4 3
output
YES
NO
YES
YES
NO
NO
Note
In the first test case of the example, it is possible to choose elements equal to 2 2 2, 3 3 3, and 6 6 6 from array a a a and elements equal to 1 1 1, 4 4 4, and 5 5 5 from array b b b. Thus, all numbers from 1 1 1 to k = 6 k=6 k=6 are included among the chosen elements.
In the second test case of the example, it can be shown that it is not possible to choose exactly three elements from each array in the required way.
In the third test case of the example, it is possible to choose elements equal to 1 1 1 and 3 3 3 from array a a a and elements equal to 2 2 2 and 4 4 4 from array b b b. Thus, all numbers from 1 1 1 to k = 4 k=4 k=4 are included among the chosen elements.
Tutorial
a a a 数组和 b b b 数组对于只有自己有的数字必须是自己拿,所以可以贪心地先将这部分拿到,判断有没有某一个数组拿的个数超过了 k 2 k \over 2 2k,如果有一个数组拿的个数超过了 k 2 k \over 2 2k 说明不满足题意,输出 N O NO NO,然后判断 a a a 数组和 b b b 数组都有的数能否将剩余的数补齐,如果能刚好补齐,则输出 Y E S YES YES,反之为 N O NO NO,时间复杂度为 O ( k ) O(k) O(k)
Solution
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
void solve() {
int n, m, k, cnt1 = 0, cnt2 = 0, cnt3 = 0;
cin >> n >> m >> k;
vector<int> a(n), b(m), mid1, mid2;
map<int, int> mp1, mp2, mp;
for (int i = 0; i < n; ++i) {
int x;
cin >> x;
mp1[x]++;
}
for (int i = 0; i < m; ++i) {
int x;
cin >> x;
mp2[x]++;
}
for (int i = 1; i <= k; ++i) {
if (mp1[i] and not mp2[i]) {
cnt1++;
} else if (mp2[i] and not mp1[i]) {
cnt2++;
} else if (mp1[i] and mp2[i]) {
cnt3++;
} else {
cout << "NO" << endl;
return;
}
}
if (cnt1 <= k / 2 and cnt2 <= k / 2) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
cout << fixed << setprecision(15);
int Test; cin >> Test; while (Test--)
solve();
return 0;
}
D. Find the Different Ones!
You are given an array a a a of n n n integers, and q q q queries.
Each query is represented by two integers l l l and r r r ( 1 ≤ l ≤ r ≤ n 1 \le l \le r \le n 1≤l≤r≤n). Your task is to find, for each query, two indices i i i and j j j (or determine that they do not exist) such that:
- l ≤ i ≤ r l \le i \le r l≤i≤r;
- l ≤ j ≤ r l \le j \le r l≤j≤r;
- a i ≠ a j a_i \ne a_j ai=aj.
In other words, for each query, you need to find a pair of different elements among a l , a l + 1 , … , a r a_l, a_{l+1}, \dots, a_r al,al+1,…,ar, or report that such a pair does not exist.
Input
The first line of the input 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 descriptions of the test 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) — the length of the array a a a.
The second line of each test case contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an ( 1 ≤ a i ≤ 1 0 6 1 \le a_i \le 10^6 1≤ai≤106) — the elements of the array a a a.
The third line of each test case contains a single integer q q q ( 1 ≤ q ≤ 2 ⋅ 1 0 5 1 \le q \le 2 \cdot 10^5 1≤q≤2⋅105) — the number of queries.
The next q q q lines contain two integers each, l l l and r r r ( 1 ≤ l < r ≤ n 1 \le l < r \le n 1≤l<r≤n) — the boundaries of the query.
It is guaranteed that the sum of the values of n n n across all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105. Similarly, it is guaranteed that the sum of the values of q q q across all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.
Output
For each query, output two integers separated by space: i i i and j j j ( l ≤ i , j ≤ r l \le i, j \le r l≤i,j≤r), for which a i ≠ a j a_i \ne a_j ai=aj. If such a pair does not exist, output i = − 1 i=-1 i=−1 and j = − 1 j=-1 j=−1.
You may separate the outputs for the test cases with empty lines. This is not a mandatory requirement.
Example
input
5
5
1 1 2 1 1
3
1 5
1 2
1 3
6
30 20 20 10 10 20
5
1 2
2 3
2 4
2 6
3 5
4
5 2 3 4
4
1 2
1 4
2 3
2 4
5
1 4 3 2 4
5
1 5
2 4
3 4
3 5
4 5
5
2 3 1 4 2
7
1 2
1 4
1 5
2 4
2 5
3 5
4 5
output
2 3
-1 -1
1 3
2 1
-1 -1
4 2
4 6
5 3
1 2
1 2
2 3
3 2
1 3
2 4
3 4
5 3
5 4
1 2
4 2
1 3
2 3
3 2
5 4
5 4
Tutorial
- 方法一:
用前缀和数组记录当前位置之前有多少个数和自己前面的数不同,对于每次查询,只需要查找第一个与 a l a_l al 不同的数的位置即可,此时前缀和数组必定是递增的,所以可以利用二分查找找到这个位置,时间复杂度 O ( n + q ⋅ l o g n ) O(n + q \cdot log\ n) O(n+q⋅log n)
- 方法二:
用数组记录当前位置前,第一个与自己不同的数的位置,对于每次查询可以直接用 O ( 1 ) O(1) O(1) 时间复杂度得到,总的时间复杂度为 O ( n ) O(n) O(n)
Solution
方法一:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; // 998244353;
void solve() {
int n, q;
cin >> n;
vector<int> a(n + 1), pre(n + 1);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
pre[i] = pre[i - 1];
if (a[i] != a[i - 1]) {
pre[i]++;
}
}
cin >> q;
while (q--) {
int l, r;
cin >> l >> r;
if (pre[r] == pre[l]) {
cout << -1 << " " << -1 << endl;
continue;
}
int j = upper_bound(pre.begin() + l, pre.begin() + r + 1, pre[l]) - pre.begin();
cout << l << " " << j << endl;
}
cout << endl;
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
cout << fixed << setprecision(15);
int Test; cin >> Test; while (Test--)
solve();
return 0;
}
方法二:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; // 998244353;
void solve() {
int n, q;
cin >> n;
vector<int> a(n + 1), diff(n + 1);
for (int i = 1; i <= n; i += 1) {
cin >> a[i];
if (a[i] == a[i - 1]) {
diff[i] = diff[i - 1];
} else {
diff[i] = i - 1;
}
}
cin >> q;
while (q--) {
int l, r;
cin >> l >> r;
if (diff[r] >= l) {
cout << diff[r] << " " << r << "\n";
} else {
cout << "-1 -1\n";
}
}
cout << endl
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
cout << fixed << setprecision(15);
int Test; cin >> Test; while (Test--)
solve();
return 0;
}
E. Klever Permutation
You are given two integers n n n and k k k ( k ≤ n k \le n k≤n), where k k k is even.
A permutation of length n n n is an array consisting of n n n distinct integers from 1 1 1 to n n n in any order. For example, [ 2 , 3 , 1 , 5 , 4 ] [2,3,1,5,4] [2,3,1,5,4] is a permutation, but [ 1 , 2 , 2 ] [1,2,2] [1,2,2] is not a permutation (as 2 2 2 appears twice in the array) and [ 0 , 1 , 2 ] [0,1,2] [0,1,2] is also not a permutation (as n = 3 n=3 n=3, but 3 3 3 is not present in the array).
Your task is to construct a k k k-level permutation of length n n n.
A permutation is called k k k-level if, among all the sums of continuous segments of length k k k (of which there are exactly n − k + 1 n - k + 1 n−k+1), any two sums differ by no more than 1 1 1.
More formally, to determine if the permutation p p p is k k k-level, first construct an array s s s of length n − k + 1 n - k + 1 n−k+1, where s i = ∑ j = i i + k − 1 p j s_i=\sum_{j=i}^{i+k-1} p_j si=∑j=ii+k−1pj, i.e., the i i i-th element is equal to the sum of p i , p i + 1 , … , p i + k − 1 p_i, p_{i+1}, \dots, p_{i+k-1} pi,pi+1,…,pi+k−1.
A permutation is called k k k-level if max ( s ) − min ( s ) ≤ 1 \max(s) - \min(s) \le 1 max(s)−min(s)≤1.
Find any k k k-level permutation of length n n n.
Input
The first line of the input 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. This is followed by the description of the test cases.
The first and only line of each test case contains two integers n n n and k k k ( 2 ≤ k ≤ n ≤ 2 ⋅ 1 0 5 2 \le k \le n \le 2 \cdot 10^5 2≤k≤n≤2⋅105, k k k is even), where n n n is the length of the desired permutation.
It is guaranteed that the sum of n n n for all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.
Output
For each test case, output any k k k-level permutation of length n n n.
It is guaranteed that such a permutation always exists given the constraints.
Example
input
5
2 2
3 2
10 4
13 4
7 4
output
1 2
3 1 2
8 3 10 1 7 4 9 2 6 5
13 4 9 1 12 5 8 2 11 6 7 3 10
1 7 3 5 2 6 4
Note
In the second test case of the example:
- p 1 + p 2 = 3 + 1 = 4 p_1 + p_2 = 3 + 1 = 4 p1+p2=3+1=4;
- p 2 + p 3 = 1 + 2 = 3 p_2 + p_3 = 1 + 2 = 3 p2+p3=1+2=3.
The maximum among the sums is 4 4 4, and the minimum is 3 3 3.
Tutorial
本题为构造体题,根据题意我们先考虑相邻两个长度为 k k k 的子数组,我们会发现前一个子数组( p i − p i + k − 1 p_i - p_{i + k - 1} pi−pi+k−1)的第一个和后一个子数组( p i + 1 − p i + k p_{i + 1} - p_{i + k} pi+1−pi+k)的最后一个元素只能相差为 1 1 1 ,因为其中间( p i + 1 − p i + k − 1 p_{i + 1} - p_{i + k - 1} pi+1−pi+k−1)都为重叠的元素。所以我们可以分成 k k k 组,每组两个相邻的元素他们的坐标之差都为 k k k,相邻两组之间一组从小到大构造,一组从大到小构造,直到所有数字都用完,即可保证所有的长度为 k k k 的子数组的总和差值都至多为 1 1 1
Solution
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
void solve() {
int n, k;
cin >> n >> k;
vector<int> ans(n + 1);
int l = 1, r = n;
for (int i = 1; i <= k; ++i) {
if (i & 1) {
for (int j = i; j <= n; j += k) {
ans[j] = l;
++l;
}
} else {
for (int j = i; j <= n; j += k) {
ans[j] = r;
--r;
}
}
}
for (int i = 1; i <= n; ++i) {
cout << ans[i] << " \n"[i == n];
}
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
cout << fixed << setprecision(15);
int Test; cin >> Test; while (Test--)
solve();
return 0;
}