首页 > 代码库 > Cover

Cover

【题目描述】

  有 N 个时间段,某个时间段可能包含其它时间段。

  请找出能包含其它时间段最多的那个段,并计算出它包括的其它时间段有多少?

 

【数据范围】

 1 <= N <= 25,000

 1 <= 时间段开始和结束点 <= 2,000,000,000

【输入格式】

 第1行:一个整数 N

 第2..N+1行:第i+1行有两个整数A,B(1 <= A < B <= 2,000,000,000)表示第 i 个时间段的开始和结束端点。任意两个时间段的端点不相同。

【输出格式】

 一行,一个整数。表示一段最多可包含的时间段数的最大值。

【样例输入】

4
1 7
2 3
5 6
4 10 

【样例输出】

2

 1 /*单调队列问题  按照左端点排一遍序 2 左端点简单入队 右端点分情况讨论  3 如果当前点Ti是右端点 并且与第一个时间点相匹配 4 则可以统计本段中的两端点都在期间的线段个数,并删除T1 5 删除T1之后如果T2的右端点已经出现过 T2可以继续删除 6 计数减一  因为他是T1-Ti的子段 不可能是最大解 7 不匹配时更加简单 计数+1  因为他一定是T1的子段  8 */ 9 #include<iostream>10 #include<cstdio>11 #include<cstring>12 #include<algorithm>13 using namespace std;14 struct self {15     int x,y;16     bool operator < (const self &a) const{17         return x<a.x;18     }19 }s[25555];20 int t[25555],q[25555],head,tail,ans,n;21 void work(){22     head=tail=1;23     q[head]=1;24     for(int i=2;i<=n;i++) {25         bool update=0;26         while(s[q[head]].y<s[i].x&&head<=tail)head++;27         for(int j=tail;j>=head;j--)28             if(s[q[j]].y>s[i].y) {29                 update=1;30                 t[q[j]]++;31                 ans=max(ans,t[q[j]]);32             }33         if(!update){34             tail++;35             q[tail]=i;36         }37     }38 }39 int main(){40     scanf("%d",&n);41     for(int i=1;i<=n;i++)42         scanf("%d%d",&s[i].x,&s[i].y);43     sort(s+1,s+n+1);44     work();45     cout<<ans<<endl;46     return 0;47 }

 

Cover