Educational Codeforces Round 165 (Rated for Div. 2 ABCDE 题)视频讲解

A. Two Friends

Problem Statement

Monocarp wants to throw a party. He has n n n friends, and he wants to have at least 2 2 2 of them at his party.

The i i i-th friend's best friend is p i p_i pi. All p i p_i pi are distinct, and for every i ∈ [ 1 , n ] i \in [1, n] i∈[1,n], p i ≠ i p_i \ne i pi=i.

Monocarp can send invitations to friends. The i i i-th friend comes to the party if both the i i i-th friend and the p i p_i pi-th friend receive an invitation (note that the p i p_i pi-th friend doesn't have to actually come to the party). Each invitation is sent to exactly one of the friends.

For example, if p = [ 3 , 1 , 2 , 5 , 4 ] p = [3, 1, 2, 5, 4] p=[3,1,2,5,4], and Monocarp sends invitations to the friends [ 1 , 2 , 4 , 5 ] [1, 2, 4, 5] [1,2,4,5], then the friends [ 2 , 4 , 5 ] [2, 4, 5] [2,4,5] will come to the party. The friend 1 1 1 won't come since his best friend didn't receive an invitation; the friend 3 3 3 won't come since he didn't receive an invitation.

Calculate the minimum number of invitations Monocarp has to send so that at least 2 2 2 friends come to the party.

Input

The first line contains one integer t t t ( 1 ≤ t ≤ 5000 1 \le t \le 5000 1≤t≤5000) --- the number of test cases.

Each test case consists of two lines:

  • the first line contains one integer n n n ( 2 ≤ n ≤ 50 2 \le n \le 50 2≤n≤50) --- the number of friends;
  • the second line contains n n n integers p 1 , p 2 , ... , p n p_1, p_2, \dots, p_n p1,p2,...,pn ( 1 ≤ p i ≤ n 1 \le p_i \le n 1≤pi≤n; p i ≠ i p_i \ne i pi=i; all p i p_i pi are distinct).

Output

Print one integer --- the minimum number of invitations Monocarp has to send.

Example

Example

input
3
5
3 1 2 5 4
4
2 3 4 1
2
2 1
output
2
3
2

Note

In the first testcase, Monocarp can send invitations to friends 4 4 4 and 5 5 5. Both of them will come to the party since they are each other's best friends, and both of them have invitations.

In the second testcase, Monocarp can send invitations to friends 1 , 2 1, 2 1,2 and 3 3 3, for example. Then friends 1 1 1 and 2 2 2 will attend: friend 1 1 1 and his best friend 2 2 2 have invitations, friend 2 2 2 and his best friend 3 3 3 have invitations. Friend 3 3 3 won't attend since his friend 4 4 4 doesn't have an invitation. It's impossible to send invitations to fewer than 3 3 3 friends in such a way that at least 2 2 2 come.

In the third testcase, Monocarp can send invitations to both friends 1 1 1 and 2 2 2, and both of them will attend.

Solution

具体见文后视频。


Code

cpp 复制代码
#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;
	cin >> n;

	std::vector<int> a(n + 1);
	for (int i = 1; i <= n; i ++)
		cin >> a[i];
	for (int i = 1; i <= n; i ++)
		if (i == a[a[i]]) {
			cout << 2 << endl;
			return;
		}
	cout << 3 << endl;
}

signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);

	int dt;
	
	cin >> dt;

	while (dt --)
		solve();

	return 0;
}

B. Shifts and Sorting

Problem Statement

Let's define a cyclic shift of some string s s s as a transformation from s 1 s 2 ... s n − 1 s n s_1 s_2 \dots s_{n-1} s_{n} s1s2...sn−1sn into s n s 1 s 2 ... s n − 1 s_{n} s_1 s_2 \dots s_{n-1} sns1s2...sn−1. In other words, you take one last character s n s_n sn and place it before the first character while moving all other characters to the right.

You are given a binary string s s s (a string consisting of only 0-s and/or 1-s).

In one operation, you can choose any substring s l s l + 1 ... s r s_l s_{l+1} \dots s_r slsl+1...sr ( 1 ≤ l < r ≤ ∣ s ∣ 1 \le l < r \le |s| 1≤l<r≤∣s∣) and cyclically shift it. The cost of such operation is equal to r − l + 1 r - l + 1 r−l+1 (or the length of the chosen substring).

You can perform the given operation any number of times. What is the minimum total cost to make s s s sorted in non-descending order?

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 and only line of each test case contains a binary string s s s ( 2 ≤ ∣ s ∣ ≤ 2 ⋅ 1 0 5 2 \le |s| \le 2 \cdot 10^5 2≤∣s∣≤2⋅105; s i ∈ s_i \in si∈ {0, 1}) --- the string you need to sort.

Additional constraint on the input: the sum of lengths of strings over all test cases doesn't exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.

Output

For each test case, print the single integer --- the minimum total cost to make string sorted using operation above any number of times.

Example

Example

input
5
10
0000
11000
101011
01101001
output
2
0
9
5
11

Note

In the first test case, you can choose the whole string and perform a cyclic shift: 10 → \rightarrow → 01. The length of the substring is 2 2 2, so the cost is 2 2 2.

In the second test case, the string is already sorted, so you don't need to perform any operations.

In the third test case, one of the optimal strategies is the next:

  1. choose substring [ 1 , 3 ] [1, 3] [1,3]: 11000 → \rightarrow → 01100;
  2. choose substring [ 2 , 4 ] [2, 4] [2,4]: 01100 → \rightarrow → 00110;
  3. choose substring [ 3 , 5 ] [3, 5] [3,5]: 00110 → \rightarrow → 00011.

The total cost is 3 + 3 + 3 = 9 3 + 3 + 3 = 9 3+3+3=9.

Solution

具体见文后视频。


Code

cpp 复制代码
#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;
	int n = s.size();
	s = ' ' + s;

	int tot = 0, res = 0;
	for (int i = 1; i <= n; i ++) 
		if (s[i] == '1')
			tot ++;
		else {
			if (!tot) continue;
			res += tot + 1;
		}

	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. Minimizing the Sum

Problem Statement

You are given an integer array a a a of length n n n.

You can perform the following operation: choose an element of the array and replace it with any of its neighbor's value.

For example, if a = [ 3 , 1 , 2 ] a=[3, 1, 2] a=[3,1,2], you can get one of the arrays [ 3 , 3 , 2 ] [3, 3, 2] [3,3,2], [ 3 , 2 , 2 ] [3, 2, 2] [3,2,2] and [ 1 , 1 , 2 ] [1, 1, 2] [1,1,2] using one operation, but not [ 2 , 1 , 2 [2, 1, 2 [2,1,2] or [ 3 , 4 , 2 ] [3, 4, 2] [3,4,2].

Your task is to calculate the minimum possible total sum of the array if you can perform the aforementioned operation at most k k k times.

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 two integers n n n and k k k ( 1 ≤ n ≤ 3 ⋅ 1 0 5 1 \le n \le 3 \cdot 10^5 1≤n≤3⋅105; 0 ≤ k ≤ 10 0 \le k \le 10 0≤k≤10).

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 ≤ 1 0 9 1 \le a_i \le 10^9 1≤ai≤109).

Additional constraint on the input: the sum of n n n over all test cases doesn't exceed 3 ⋅ 1 0 5 3 \cdot 10^5 3⋅105.

Output

For each test case, print a single integer --- the minimum possible total sum of the array if you can perform the aforementioned operation at most k k k times.

Example

input
4
3 1
3 1 2
1 3
5
4 2
2 2 1 3
6 3
4 1 2 2 4 3
output
4
5
5
10

Note

In the first example, one of the possible sequences of operations is the following: [ 3 , 1 , 2 ] → [ 1 , 1 , 2 [3, 1, 2] \rightarrow [1, 1, 2 [3,1,2]→[1,1,2].

In the second example, you do not need to apply the operation.

In the third example, one of the possible sequences of operations is the following: [ 2 , 2 , 1 , 3 ] → [ 2 , 1 , 1 , 3 ] → [ 2 , 1 , 1 , 1 ] [2, 2, 1, 3] \rightarrow [2, 1, 1, 3] \rightarrow [2, 1, 1, 1] [2,2,1,3]→[2,1,1,3]→[2,1,1,1].

In the fourth example, one of the possible sequences of operations is the following: [ 4 , 1 , 2 , 2 , 4 , 3 ] → [ 1 , 1 , 2 , 2 , 4 , 3 ] → [ 1 , 1 , 1 , 2 , 4 , 3 ] → [ 1 , 1 , 1 , 2 , 2 , 3 ] [4, 1, 2, 2, 4, 3] \rightarrow [1, 1, 2, 2, 4, 3] \rightarrow [1, 1, 1, 2, 4, 3] \rightarrow [1, 1, 1, 2, 2, 3] [4,1,2,2,4,3]→[1,1,2,2,4,3]→[1,1,1,2,4,3]→[1,1,1,2,2,3].

Solution

具体见文后视频。


Code

cpp 复制代码
#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 = 3e5 + 20;

int n, k;
int a[N], f[N][20];
int mn[N][20];

void build() {
	int m = log2(n) + 1;
	for (int j = 0; j < m; j ++)
		for (int i = 1; i <= n - (1ll << j) + 1; i ++)
			if (!j) mn[i][j] = a[i] - a[i - 1];
			else mn[i][j] = min(mn[i][j - 1], mn[i + (1ll << j - 1)][j - 1]);
}
int query(int l, int r) {
	int t = log2(r - l + 1);
	return min(mn[l][t], mn[r - (1ll << t) + 1][t]);
}

void solve() {
	cin >> n >> k;

	for (int i = 1; i <= n; i ++)
		cin >> a[i], a[i] += a[i - 1];

	for (int i = 0; i <= n; i ++)
		for (int j = 0; j <= k; j ++)
			f[i][j] = -1e16;
	build();
	f[0][k] = 0;
	for (int i = 1; i <= n; i ++)
		for (int t = 0; t <= k; t ++) {
			f[i][t] = f[i - 1][t];
			for (int j = max(1ll, i - k); j <= i; j ++) {
				if (t + (i - j) <= k)
					f[i][t] = max(f[i][t], f[j - 1][t + (i - j)] + a[i] - a[j - 1] - query(j, i) * (i - j + 1));
			}
		}

	int res = 0;
	for (int i = 0; i <= k; i ++)
		res = max(res, f[n][i]);
	cout << a[n] - res << endl;
	for (int i = 0; i <= n; i ++)
		a[i] = 0;

}

signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);

	int dt;
	
	cin >> dt;

	while (dt --)
		solve();

	return 0;
}

D. Shop Game

Problem Statement

Alice and Bob are playing a game in the shop. There are n n n items in the shop; each item has two parameters: a i a_i ai (item price for Alice) and b i b_i bi (item price for Bob).

Alice wants to choose a subset (possibly empty) of items and buy them. After that, Bob does the following:

  • if Alice bought less than k k k items, Bob can take all of them for free;
  • otherwise, he will take k k k items for free that Alice bought (Bob chooses which k k k items it will be), and for the rest of the chosen items, Bob will buy them from Alice and pay b i b_i bi for the i i i-th item.

Alice's profit is equal to ∑ i ∈ S b i − ∑ j ∈ T a j \sum\limits_{i \in S} b_i - \sum\limits_{j \in T} a_j i∈S∑bi−j∈T∑aj, where S S S is the set of items Bob buys from Alice, and T T T is the set of items Alice buys from the shop. In other words, Alice's profit is the difference between the amount Bob pays her and the amount she spends buying the items.

Alice wants to maximize her profit, Bob wants to minimize Alice's profit. Your task is to calculate Alice's profit if both Alice and Bob act optimally.

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 two integers n n n and k k k ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \le n \le 2 \cdot 10^5 1≤n≤2⋅105; 0 ≤ k ≤ n 0 \le k \le n 0≤k≤n).

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 ≤ 1 0 9 1 \le a_i \le 10^9 1≤ai≤109).

The third line contains n n n integers b 1 , b 2 , ... , b n b_1, b_2, \dots, b_n b1,b2,...,bn ( 1 ≤ b i ≤ 1 0 9 1 \le b_i \le 10^9 1≤bi≤109).

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 --- Alice's profit if both Alice and Bob act optimally.

Example

Example

input
4
2 0
2 1
1 2
4 1
1 2 1 4
3 3 2 3
4 2
2 1 1 1
4 2 3 2
6 2
1 3 4 9 1 3
7 6 8 10 6 8
output
1
1
0
7

Note

In the first test case, Alice should buy the 2 2 2-nd item and sell it to Bob, so her profit is 2 − 1 = 1 2 - 1 = 1 2−1=1.

In the second test case, Alice should buy the 1 1 1-st, the 2 2 2-nd and the 3 3 3-rd item; then Bob takes the 1 1 1-st item for free and pays for the 2 2 2-nd and the 3 3 3-rd item. Alice's profit is ( 3 + 2 ) − ( 1 + 2 + 1 ) = 1 (3+2) - (1+2+1) = 1 (3+2)−(1+2+1)=1. Bob could take 2 2 2-nd item for free instead; this does not change Alice's profit. Bob won't take the 3 3 3-rd item for free, since this would lead to a profit of 2 2 2.

Solution

具体见文后视频。

Code

cpp 复制代码
#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;

int n, k;
PII item[N], cpy[N];

void solve() {
	cin >> n >> k;

	for (int i = 1; i <= n; i ++)
		cin >> item[i].fi;
	for (int i = 1; i <= n; i ++)
		cin >> item[i].se, cpy[i] = item[i];

	if (!k) {
		int res = 0;
		for (int i = 1; i <= n; i ++)
			res += max(0ll, item[i].se - item[i].fi);
		cout << res << endl;
		return;
	}

	sort(item + 1, item + 1 + n, [&](PII a, PII b) {
		if (a.se == b.se) return a.fi > b.fi;
		return a.se < b.se;
	});
	
	int tot = 0, res = 0, sum = 0;
	for (int i = 1; i <= n; i ++)
		sum += max(0ll, item[i].se - item[i].fi);

	multiset<int> s;
	for (int i = n; i >= n - k + 1; i --) {
		s.insert(item[i].fi), tot += item[i].fi;
		sum -= max(0ll, item[i].se - item[i].fi);
	}
	
	for (int i = n - k; i >= 0; i --) {
		// cout << item[i].se << ":" << sum << " " << tot << "->" << sum - tot << endl;
		res = max(res, sum - tot);
		auto it = s.end();
		it --;
		if (*it > item[i].fi) {
			tot -= *it, s.erase(it), s.insert(item[i].fi), tot += item[i].fi;
		}
		sum -= max(0ll, item[i].se - item[i].fi);
	}

	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;
}

E. Unique Array

Problem Statement

You are given an integer array a a a of length n n n. A subarray of a a a is one of its contiguous subsequences (i. e. an array [ a l , a l + 1 , ... , a r ] [a_l, a_{l+1}, \dots, a_r] [al,al+1,...,ar] for some integers l l l and r r r such that 1 ≤ l < r ≤ n 1 \le l < r \le n 1≤l<r≤n). Let's call a subarray unique if there is an integer that occurs exactly once in the subarray.

You can perform the following operation any number of times (possibly zero): choose an element of the array and replace it with any integer.

Your task is to calculate the minimum number of aforementioned operation in order for all the subarrays of the array a a a to be unique.

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 ≤ 3 ⋅ 1 0 5 1 \le n \le 3 \cdot 10^5 1≤n≤3⋅105).

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 ≤ n 1 \le a_i \le n 1≤ai≤n).

Additional constraint on the input: the sum of n n n over all test cases doesn't exceed 3 ⋅ 1 0 5 3 \cdot 10^5 3⋅105.

Output

For each test case, print a single integer --- the minimum number of aforementioned operation in order for all the subarrays of the array a a a to be unique.

Example

input
4
3
2 1 2
4
4 4 4 4
5
3 1 2 1 2
5
1 3 2 1 2
output
0
2
1
0

Note

In the second test case, you can replace the 1 1 1-st and the 3 3 3-rd element, for example, like this: [ 3 , 4 , 1 , 4 ] [3, 4, 1, 4] [3,4,1,4].

In the third test case, you can replace the 4 4 4-th element, for example, like this: [ 3 , 1 , 2 , 3 , 2 ] [3, 1, 2, 3, 2] [3,1,2,3,2].

Solution

具体见文后视频。


Code

cpp 复制代码
#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 = 3e5 + 10;

int n;
int a[N], l[N], r[N], p[N];
struct Segment {
	int l, r;
	int mn, len, lazy;
}tr[N << 2];
int q[N], hh, tt, f[N];

void pushup(int u) {
	tr[u].mn = min(tr[u << 1].mn, tr[u << 1 | 1].mn), tr[u].len = 0;
	if (tr[u << 1].mn == tr[u].mn) tr[u].len += tr[u << 1].len;
	if (tr[u << 1 | 1].mn == tr[u].mn) tr[u].len += tr[u << 1 | 1].len;
}

void pushdown(int u) {
	if (tr[u].lazy) {
		tr[u << 1].mn += tr[u].lazy, tr[u << 1].lazy += tr[u].lazy;
		tr[u << 1 | 1].mn += tr[u].lazy, tr[u << 1 | 1].lazy += tr[u].lazy;
		tr[u].lazy = 0;
	}
}

void build(int u, int l, int r) {
	tr[u] = {l, r}, tr[u].len = r - l + 1;
	if (l == r) return;
	int mid = l + r >> 1;
	build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
}

void modify(int u, int l, int r, int d) {
	if (tr[u].l >= l && tr[u].r <= r) {
		tr[u].mn += d, tr[u].lazy += d;
		return;
	}
	pushdown(u);
	int mid = tr[u].l + tr[u].r >> 1;
	if (mid >= l) modify(u << 1, l, r, d);
	if (mid < r) modify(u << 1 | 1, l, r, d);
	pushup(u);
}

int query(int u, int l, int r) {
	if (tr[u].l >= l && tr[u].r <= r) {
		if (tr[u].mn > 0) return tr[u].r - tr[u].l + 1;
		return tr[u].r - tr[u].l + 1 - tr[u].len;
	}

	pushdown(u);
	int mid = tr[u].l + tr[u].r >> 1, res = 0;
	if (mid >= l) res += query(u << 1, l, r);
	if (mid < r) res += query(u << 1 | 1, l, r);
	return res;
}

void solve() {
	cin >> n;

	for (int i = 1; i <= n; i ++) p[i] = 0;
	for (int i = 1; i <= n; i ++)
		cin >> a[i], l[i] = p[a[i]] + 1, p[a[i]] = i;
	for (int i = 1; i <= n; i ++) p[i] = n + 1;
	for (int i = n; i >= 1; i --)
		r[i] = p[a[i]] - 1, p[a[i]] = i;
	// (l[i], i) -> (i, r[i])
	std::vector<array<int, 4>> opr;
	for (int i = 1; i <= n; i ++) {
		opr.push_back({i, l[i], i, 1});
		opr.push_back({r[i] + 1, l[i], i, -1});
	}
	sort(opr.begin(), opr.end());
	build(1, 1, n);

	q[0] = 0, q[ ++ tt] = 1, hh = 0, tt = 0, f[1] = 1;
	int lim = 0;
	for (int i = 1, j = 0; i <= n; i ++) {
		while (j < opr.size() && opr[j][0] == i) {
			modify(1, opr[j][1], opr[j][2], opr[j][3]);
			j ++;
		}
		int l = 1, r = i;
		while (l < r) {
			int mid = l + r + 1 >> 1;
			if (query(1, mid, i) == i - mid + 1) r = mid - 1;
			else l = mid;
		}
		if (query(1, 1, i) == i) p[i] = 0;
		else p[i] = l;
		lim = max(lim, p[i]);
		while (hh <= tt && q[hh] < lim) hh ++;
		f[i + 1] = f[q[hh]] + 1;
		while (hh <= tt && f[q[tt]] > f[i + 1]) tt --;
		q[ ++ tt] = i + 1;
	}
	
	int res = 2e9;
	for (int i = lim; i <= n; i ++)
		res = min(res, f[i]);
	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;
}

视频讲解

Educational Codeforces Round 165 (Rated for Div. 2)(A ~ E 题讲解)


最后祝大家早日

相关推荐
XiaoLeisj17 分钟前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
yuyanjingtao32 分钟前
CCF-GESP 等级考试 2023年9月认证C++四级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试
Jasmine_llq37 分钟前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
charlie1145141911 小时前
C++ STL CookBook
开发语言·c++·stl·c++20
Lenyiin1 小时前
01.02、判定是否互为字符重排
算法·leetcode
小林熬夜学编程1 小时前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
倔强的石头1061 小时前
【C++指南】类和对象(九):内部类
开发语言·c++
鸽鸽程序猿1 小时前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列