AcWing 6100. 奶牛选美
问题描述
约翰举办了奶牛选美大赛,一共有 n
头奶牛参赛,编号为 1 ∼ n
。
比赛将进行 m
轮,其中第 i
轮比赛由第 lᵢ ∼ rᵢ
头奶牛(包括 lᵢ
和 rᵢ
)中未被淘汰的所有奶牛共同参赛。
经过激烈角逐后,第 xᵢ
头奶牛击败本轮参赛的其余所有奶牛,胜者留存,败者淘汰。
在 m
轮比赛结束后,除了第 m
轮比赛的获胜者 xₘ
外,其余 n - 1
头奶牛在此前的比赛中尽数淘汰,因此 xₘ
荣获冠军。
你的任务是:确定每头奶牛是被谁击败的。
输入格式
- 第一行包含两个整数
n
和m
。 - 接下来
m
行,每行包含三个整数lᵢ
、rᵢ
、xᵢ
,表示第i
轮比赛的信息。
输入保证数据合法,且每一轮比赛中至少有两头奶牛参与。
输出格式
- 输出一行包含
n
个整数,第i
个数表示击败第i
头奶牛的编号。 - 如果第
i
头奶牛是最终冠军,则输出0
。
数据范围
- 前 6 个测试点满足:
2 ≤ n ≤ 10
- 所有测试点满足:
2 ≤ n ≤ 3×10⁵
1 ≤ m ≤ 3×10⁵
1 ≤ lᵢ < rᵢ ≤ n
lᵢ ≤ xᵢ ≤ rᵢ
输入样例 1
4 3
1 2 1
1 3 3
1 4 4
输出样例 1
3 1 4 0
输入样例 2
8 4
3 5 4
3 7 6
2 8 8
1 8 1
输出样例 2
0 8 4 6 4 8 6 1
c++代码
#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;
int n, m, l, r, x;
int arr[300005], ans[300005];
int myfind(int x) {
int root = x;
while(arr[root] != root) root = arr[root];
int i = x, j;
while(i != root) {
j = arr[i];
arr[i] = root;
i = j;
}
return root;
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 1; i <= n + 1; i++) arr[i] = i;
while(m--) {
scanf("%d %d %d", &l, &r, &x);
for (int i = l; i < x;) {
i = myfind(i);
if (i < x) arr[i] = i + 1, ans[i] = x;
}
for (int i = x + 1; i <= r; ) {
i = myfind(i);
if (i <= r) arr[i] = i + 1, ans[i] = x;
}
}
for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
return 0;
}//by wqs