看电视

来源:互联网 发布:网页读取串口数据 编辑:程序博客网 时间:2024/06/11 17:07

> 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可能大于任意区间的左端点

原创粉丝点击