Codeforces Round #207 (Div. 1) A:http://codeforces.com/problemset/problem/356/A
题意:给你n匹马,然后有m场比赛。每场比赛有一个l,r,x,表示编号从l,r之间的马都被x给打败了,但是这里如果之前已经败了,那么这里的区间就不会包括了。
题解:题解,直接用一个set搞定。
思维过程:首先,想到,对于一场比赛来说,如果之前已经败了的话,这里就不用在考虑了,但是如何判断这个区间里面的马已经败了,朴素的想法,就是查询还是在这个区间,但是我把之前的已经败的马打上表示,然后再在这个区间内逐个进行判断,这样判断的话,区间内的每个元素都会被判断一次,可想而知,这样的想法是不对。时间复杂度hold不住。如何对于那些已经败的马不用判断。这里,可以用一个set来搞,把所有的元素放进set,当要删除一个区间的时候,只要用lower_bound找到第一个不小于l的数,然后往后找,直到到达右端点。然后把找到的点,从set中删除即可。这样,每次查询只在没有删除的马中进行,所以减少了许多不必要的判断。现在考虑复杂度。每个数,会被放进set和从set中删除一次,所以复杂度是n(logn).一定要利用题目中的各种信息,然后利用好自己的思维信息,寻找突破口,一点一滴的,总会有解决的方法。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<set> 6 using namespace std; 7 const int N=3e5+10; 8 int ans[N],temp[N],top; 9 int n,m,l,r,x; 10 int main(){ 11 while(~scanf("%d%d",&n,&m)){ 12 set<int>Q; 13 for(int i=1;i<=n;i++){ 14 Q.insert(i); 15 } 16 for(int i=1;i<=m;i++){ 17 scanf("%d%d%d",&l,&r,&x); 18 top=0; 19 set<int>::iterator it=Q.lower_bound(l); 20 for(;it!=Q.end();it++){ 21 if((*it)>r)break; 22 if((*it)==x){ 23 ans[x]=x; 24 } 25 else{ 26 ans[(*it)]=x; 27 temp[++top]=(*it); 28 } 29 } 30 for(int i=1;i<=top;i++){ 31 Q.erase(temp[i]); 32 } 33 top=0; 34 } 35 for(int i=1;i<n;i++){ 36 if(ans[i]==i)printf("0 "); 37 else 38 printf("%d ",ans[i]); 39 } 40 if(ans[n]==n)printf("0 "); 41 else 42 printf("%d ",ans[n]); 43 } 44 45 46 47 }