P10134 [USACO24JAN] Cowmpetency S
题目描述
Farmer John 正在为他的奶牛们雇用一位新的牛群领队。为此,他面试了 NNN(2≤N≤1052\le N\le 10^52≤N≤105)头奶牛来担任该职位。在面试第 iii 个候选牛后,他会为候选牛分配一个 111 到 CCC(1≤C≤1091\le C\le 10^91≤C≤109)范围内的整数「牲任力」分数 cic_ici,与她们的领导能力相关。
由于 Farmer John 面试了如此多的奶牛,他没能记得所有奶牛的牲任力分数。然而,他确实记得 QQQ(1≤Q<N1\le Q<N1≤Q<N)对数字 (aj,hj)(a_j,h_j)(aj,hj),其中奶牛 hjh_jhj 是第一头比奶牛 111 到 aja_jaj 拥有严格更高牲任力分数的奶牛(所以 1≤aj<hj≤N1\le a_j<h_j\le N1≤aj<hj≤N)。
Farmer John 现在告诉你序列 c1,…,cNc_1,\ldots,c_Nc1,…,cN
(其中 ci=0c_i=0ci=0 表示他忘记了奶牛 iii 的牲任力分数)和 QQQ 对 (aj,hj)(a_j,h_j)(aj,hj)。帮助他求出与此信息一致的最小字典序的牲任力分数序列,或者判断不存在这样的序列!如果一个分数序列比另一个分数序列于这两个序列不同的第一个位置上的奶牛分配了更小的分数,则这个分数序列的字典序更小。
每个测试点包含 TTT(1≤T≤201\le T\le 201≤T≤20)个独立的测试用例。输入保证所有测试用例的 NNN 之和不超过 3⋅1053\cdot 10^53⋅105。
输入格式
输入的第一行包含 TTT,独立的测试用例的数量。每个测试用例描述如下:
- 第一行包含 NNN,QQQ 和 CCC。
- 第二行包含序列 c1,…,cNc_1,\ldots,c_Nc1,…,cN(0≤ci≤C0\le c_i\le C0≤ci≤C)。
- 最后 QQQ 行,每行包含一个数对 (aj,hj)(a_j,h_j)(aj,hj)。输入保证同一测试用例内的所有 aja_jaj 各不相同。
输出格式
对于每个测试用例,输出一行,包含与 Farmer John 记忆一致的最小字典序牲任力分数序列,或者如果这样的序列不存在时输出 −1−1−1。
输入输出样例 #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)=1,c2=2c_2=2c2=2 且 1<21<21<2,故第一个数对是满足的
- max(c1,c2,c3)=2\max(c_1,c_2,c_3)=2max(c1,c2,c3)=2,c4=3c_4=3c4=3 且 2<32<32<3,故第二个数对是满足的
- max(c1,c2,c3,c4)=3\max(c_1,c_2,c_3,c_4)=3max(c1,c2,c3,c4)=3,c5=4c_5=4c5=4 且 3<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_1a1 和 h1h_1h1 告诉我们奶牛 666 是第一头分数严格高于奶牛 111 到 444 的奶牛。因此,奶牛 111 到 666 的最高得分是奶牛 666,为 555。由于奶牛 777 的分数为 777,所以奶牛 777 是第一头比奶牛 111 到 666 得分更高的奶牛。因此,第二个陈述「奶牛 999 是第一头比奶牛 111 到 666 得分更高的奶牛」不能成立。
测试点性质
- 测试点 333:N≤10N \le 10N≤10 且 Q,C≤4Q,C\le 4Q,C≤4。
- 测试点 4−84-84−8:N≤1000N\le 1000N≤1000。
- 测试点 9−129-129−12:没有额外限制。
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考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
用C++实现信奥题 P10134 USACO24JAN Cowmpetency S&spm=1001.2101.3001.5002&articleId=162386309&d=1&t=3&u=e8e987a98e4a47c187b527540276f71d)
472

被折叠的 条评论
为什么被折叠?



