1172: 谁败给了谁
Time Limit: 0 Sec Memory Limit: 128 MBSubmit: 2 Solved: 2
[ Submit][ Status][ Web Board]
Description
有n个人编号从1到n进行一场比赛,比赛依次进行m轮,告诉你每场比赛的信息li, ri, xi,表示第i轮在编号在li~ri之间且尚未被打败的人中进行,胜者是xi(编号xi的人打败了这一轮中除他以外的参与者),请你算出每个人是被谁打败的。
Input
第一行一个正整数t(t<=20),表示数据组数。 对于每组数据,第一行两个正整数n(2<=n<=300000),m(1<=m<=300000); 接下来的m行,每行3个正整数li, ri, xi(1<=li,ri<=n;li<=xi<=ri),表示第i轮的信息。
Output
对于每组数据,一行输出n个数,第i个数表示打败第i个人的人的编号,对于最终胜者这个数是0,每个数间用空格隔开。对于每组数据,一行输出n个数,第i个数表示打败第i个人的人的编号,对于最终胜者这个数是0,每个数间用空格隔开。
Sample Input
2 4 3 1 2 1 1 3 3 1 4 4 8 4 3 5 4 3 7 6 2 8 8 1 8 1
Sample Output
3 1 4 0 0 8 4 6 4 8 6 1
HINT
暴力的话,会TLE,就别试啦.
题意:中文很清楚。
思路:用vector随时删除已经被打败的人,另外加二分提高查找效率。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
int ans[300010];
int main()
{ int t,n,m,i,j,k,l,r,p,l2,r2,mi;
scanf("%d",&t);
while(t--)
{ scanf("%d%d",&n,&m);
vector<int> v;
vector<int>::iterator iv;
for(i=1;i<=n;i++)
{ ans[i]=0;
v.push_back(i);
}
while(m--)
{ scanf("%d%d%d",&l,&r,&k);
l2=0;r2=v.size()-1;
while(l2<r2)
{ mi=(l2+r2)/2;
if(v[mi]<l)
l2=mi+1;
else
r2=mi;
}
for(i=l2;i<v.size();i++)
{ p=v[i];
if(p>r)
break;
else if(p==k)
continue;
else
{ ans[p]=k;
v.erase(v.begin()+i);
i--;
}
}
}
printf("%d",ans[1]);
for(i=2;i<=n;i++)
printf(" %d",ans[i]);
printf("\n");
}
}