您的位置:首页 > 其它

看电视

2017-09-26 16:25 120 查看

> 2957.看电视

题目描述 最近有很多好看的电视节目要更新了。用[a,b]这个区间表示一个节目的播放时间。乐乐想知道如果他在[x,y]这段时间内有空,最多可以看多少个节目。请你帮他算算。

输入 第一行两个整数n,表示节目数。 接下来n行,每行两个整数a、b,表示一个节目在a时刻开始,在b时刻结束。第n+1行,一个整数m,表示有m个询问。 接下里m行,每行两个整数x、y。表示乐乐在这段时间内有空。

输出 对于每个询问,输出一个整数,表示乐乐最多可以看到的电视节目数

70%的数据,n的范围[1,5000],m的范围[1,2000],节目和询问时间[1,10^5];

100%的数据,n的范围[1,10^5],m的范围[1,10^5],节目和询问时间[1,10^9];

这是一道很经典的贪心

按尾排序 找到第一个满足条件的区间 然后for一遍即可

这样复杂度是m*n 刚好可以水70分

然后需要优化

首先频道之间的关系至始至终没有改变

并且每个频道之间都有固定的关系

ps:(只要时间允许,看完这部频道之后可以知道要看哪个频道)

所以可以跳着走哩

倍增上:

now=1;
FOR(i,1,n){
while(R[i]>L[now]&&now<=n)now++;
if(now>n)break;
fa[i][0]=now;
}
FOR(k,1,17)FOR(i,1,n)fa[i][k]=fa[fa[i][k-1]][k-1];
int m;
cin>>m;
while(m--){
int x,y;
scanf("%d %d",&x,&y);
int id=lower_bound(L+1,L+n+1,x)-L;
if(R[id]>y||id==n+1){puts("0");continue;}
int res=1;
DOR(i,17,0){
if(fa[id][i]==0)continue;
if(R[fa[id][i]]>y)continue;
id=fa[id][i];
res+=1<<i;
}
printf("%d\n",res);
}


上面还有一个处理就是当一个大区间覆盖一个小区间时,应把到区间去掉

这样可以保证它的头和尾都是单调递增的

然后就根据传入的x二分查找最小的L(满足L>=x)

注意传入的x可能大于任意区间的左端点
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: