问题描述
赛马场有 n
匹马,编号分别为 1,2,⋯,n 。进行 m 次淘汰赛,决出他们当中速度最快的一匹马。每次淘汰赛所有编号在区间 [L,R] 并且没有被淘汰的马参加比赛,其中编号为 p 的马获胜,其他的马都被淘汰。 m
次淘汰赛之后,只有一匹马未被淘汰。求所有被淘汰的每一匹马是被哪一匹马淘汰的。
输入格式
第一行包含两个整数 n,m
。 接下来 m 行每行包含三个整数 L,R,p
。
输出格式
输出一行,包含 n
个整数,两个整数之间使用空格分隔。分别表示第 i 个整数表示淘汰第 i 匹马的马的编号。如果第 i 匹马是最终的胜利者,则输出 0
。
样例输入
5 3
2 4 3
1 3 1
1 5 5
样例输出
5 3 1 3 0
数据规模和约定
对于 30% 数据: n≤1000
对于 100%
数据: 1≤m < n≤300000,1≤L≤p≤R≤n
输入保证每场比赛 L
到 R 之间至少有两匹马没有被淘汰,并且第 p 匹马没有被淘汰。
思路详解
这道题比较水,模拟+技巧 即可
双重循环模拟
只需要注意用一个last数组维护每匹马右边(即需要处理的下一匹)没有被out的第一匹马,以此为跳板,跳一跳,在内层循环中跳过已经out的马。
#include <bits/stdc++.h>
using namespace std;
int n,m;
int last[300010];
int ans[300010];
int main(){
cin>>n>>m;
for (int i = 1; i <= m; i++){
int l,r,p;
cin>>l>>r>>p;
for (int j = l; j <= r; j++){
if(!last[j] && !ans[j] && j != p){
ans[j]=p;
last[j]=r;
}else if (last[j]){
if (!ans[ans[j]]){
if (ans[j] <= r && ans[j] >= l && ans[j] != p){
ans[ans[j]] = p;
last[ans[j]] = max(last[ans[j]],r);
}
}
j=last[j]; //跳过已out出局的马
}
}
}
cout<<ans[1];
for (int i = 2; i <= n; i++){
cout<<" "<<ans[i];
}
return 0;
}