打卡信奥刷题(3413)用C++实现信奥题 P10134 [USACO24JAN] Cowmpetency S

P10134 [USACO24JAN] Cowmpetency S

题目描述

Farmer John 正在为他的奶牛们雇用一位新的牛群领队。为此,他面试了 NNN2≤N≤1052\le N\le 10^52N105)头奶牛来担任该职位。在面试第 iii 个候选牛后,他会为候选牛分配一个 111CCC1≤C≤1091\le C\le 10^91C109)范围内的整数「牲任力」分数 cic_ici,与她们的领导能力相关。

由于 Farmer John 面试了如此多的奶牛,他没能记得所有奶牛的牲任力分数。然而,他确实记得 QQQ1≤Q<N1\le Q<N1Q<N)对数字 (aj,hj)(a_j,h_j)(aj,hj),其中奶牛 hjh_jhj 是第一头比奶牛 111aja_jaj 拥有严格更高牲任力分数的奶牛(所以 1≤aj<hj≤N1\le a_j<h_j\le N1aj<hjN)。

Farmer John 现在告诉你序列 c1,…,cNc_1,\ldots,c_Nc1,,cN
(其中 ci=0c_i=0ci=0 表示他忘记了奶牛 iii 的牲任力分数)和 QQQ(aj,hj)(a_j,h_j)(aj,hj)。帮助他求出与此信息一致的最小字典序的牲任力分数序列,或者判断不存在这样的序列!如果一个分数序列比另一个分数序列于这两个序列不同的第一个位置上的奶牛分配了更小的分数,则这个分数序列的字典序更小。

每个测试点包含 TTT1≤T≤201\le T\le 201T20)个独立的测试用例。输入保证所有测试用例的 NNN 之和不超过 3⋅1053\cdot 10^53105

输入格式

输入的第一行包含 TTT,独立的测试用例的数量。每个测试用例描述如下:

  1. 第一行包含 NNNQQQCCC
  2. 第二行包含序列 c1,…,cNc_1,\ldots,c_Nc1,,cN0≤ci≤C0\le c_i\le C0ciC)。
  3. 最后 QQQ 行,每行包含一个数对 (aj,hj)(a_j,h_j)(aj,hj)。输入保证同一测试用例内的所有 aja_jaj 各不相同。

输出格式

对于每个测试用例,输出一行,包含与 Farmer John 记忆一致的最小字典序牲任力分数序列,或者如果这样的序列不存在时输出 −1−11

输入输出样例 #1

输入 #1

1
7 3 5
1 0 2 3 0 4 0
1 2
3 4
4 5

输出 #1

1 2 2 3 4 4 1

输入输出样例 #2

输入 #2

5
7 6 10
0 0 0 0 0 0 0
1 2
2 3
3 4
4 5
5 6
6 7
8 4 9
0 0 0 0 1 6 0 6
1 3
6 7
4 7
2 3
2 1 1
0 0
1 2
10 4 10
1 2 0 2 1 5 8 6 0 3
4 7
1 2
5 7
3 7
10 2 8
1 0 0 0 0 5 7 0 0 0
4 6
6 9

输出 #2

1 2 3 4 5 6 7
1 1 2 6 1 6 7 6
-1
1 2 5 2 1 5 8 6 1 3
-1

说明/提示

样例解释 1

我们可以看到给定的输出满足所有 Farmer John 记得的数对。

  • max⁡(c1)=1\max(c_1)=1max(c1)=1c2=2c_2=2c2=21<21<21<2,故第一个数对是满足的
  • max⁡(c1,c2,c3)=2\max(c_1,c_2,c_3)=2max(c1,c2,c3)=2c4=3c_4=3c4=32<32<32<3,故第二个数对是满足的
  • max⁡(c1,c2,c3,c4)=3\max(c_1,c_2,c_3,c_4)=3max(c1,c2,c3,c4)=3c5=4c_5=4c5=43<43<43<4,故第三个数对是满足的

存在一些其他的序列与 Farmer John 的记忆相一致,如

1 2 2 3 5 4 11\ 2\ 2\ 3\ 5\ 4\ 11 2 2 3 5 4 1
1 2 2 3 4 4 51\ 2\ 2\ 3\ 4\ 4\ 51 2 2 3 4 4 5

然而,其中没有序列比给定的输出字典序更小。

样例解释 2

在测试用例 333 中,由于 C=1C=1C=1,唯一可能的序列是

1 11\ 11 1

然而,在这种情况下,奶牛 222 的分数并不比奶牛 111 高,因此我们无法满足条件。

在测试用例 555 中,a1a_1a1h1h_1h1 告诉我们奶牛 666 是第一头分数严格高于奶牛 111444 的奶牛。因此,奶牛 111666 的最高得分是奶牛 666,为 555。由于奶牛 777 的分数为 777,所以奶牛 777 是第一头比奶牛 111666 得分更高的奶牛。因此,第二个陈述「奶牛 999 是第一头比奶牛 111666 得分更高的奶牛」不能成立。

测试点性质

  • 测试点 333N≤10N \le 10N10Q,C≤4Q,C\le 4Q,C4
  • 测试点 4−84-848N≤1000N\le 1000N1000
  • 测试点 9−129-12912:没有额外限制。

C++实现

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
struct Node { int u, v; } b[N];
int n, q, c, a[N], lst[N], dsu[N], tag[N], pre[N];
void Solve() {
	scanf("%d%d%d", &n, &q, &c);
	for(int i = 1; i <= n; ++i) scanf("%d", &a[i]), lst[i] = a[i] ? lst[i - 1] : i;
	for(int i = 1, u, v; i <= q; ++i) scanf("%d%d", &u, &v), b[i] = {u, v - 1};
	for(int i = 1; i <= n; ++i) dsu[i] = i + 1;
	for(int i = 1; i <= q; ++i) dsu[b[i].u] = b[i].v + 1, tag[b[i].v + 1] = 1;
	pre[0] = 1;
	for(int i = 1; i <= n; ++i) { // 求出每个点的 pre
		pre[i] = pre[i - 1] + tag[i];
		for(int j = i; j < dsu[i]; ++j) pre[i] = max(pre[i], a[j]);
		for(int j = i; j < dsu[i]; ++j) pre[j] = pre[i];
		i = dsu[i] - 1;
	}
	bool isOK = 1;
	for(int i = 1; i <= n; ++i) { // 根据 pre 求出 a
		if(!a[i]) a[i] = pre[i - 1] == pre[i] ? 1 : pre[i];
		else if(pre[i] != pre[i - 1] && pre[i] > a[i])  {
			if(lst[i]) a[lst[i]] = pre[i];
		}
		if(a[i] > c) isOK = 0;
		pre[i] = max({pre[i], pre[i - 1], a[i]});
		tag[i] = 0;
	}
	for(int i = 1; i <= n; ++i) pre[i] = max(pre[i - 1], a[i]);
	for(int i = 1; i <= q; ++i) 
		if(pre[b[i].u] < pre[b[i].v] || pre[b[i].u] == pre[b[i].v + 1]) isOK = 0;
	if(!isOK) printf("-1\n");
	else for(int i = 1; i <= n; ++i)
		printf("%d%c", a[i], i == n ? '\n' : ' ');
}
int main() {
	int t; scanf("%d", &t);
	while(t--) Solve();
	return 0;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值