题意:给你n条线段[l,r]以及m组询问,每组询问给出一组[l,r],问至少需要取多少个线段可以覆盖[l,r]区间中所有的点。

如果贪心地做的话,可以求出“从每个左端点l出发选一条线段可以到达的最右端点”,然后一直往右跳直到跳到r为止,但最坏情况下需要跳O(n)次显然是会T的,那咋办呢?

我们拓展一下,利用倍增的方法,可以预处理出“从每个左端点l出发选2^k条线段可以到达的最右端点”,设为$dp[l][k]$,则有$dp[l][k]=dp[dp[l][k-1]][k-1]$,对于每组询问,让k从大到小依次尝试,如果从l跳2^k步跳不到到r,那么答案就加上2^k。(非常类似于树上倍增求LCA的过程)

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+,inf=0x3f3f3f3f;
int dp[N][],n,m;
int main() {
scanf("%d%d",&n,&m);
while(n--) {
int l,r;
scanf("%d%d",&l,&r);
dp[l][]=max(dp[l][],r);
}
for(int i=; i<N; ++i)dp[i][]=max(dp[i][],dp[i-][]);
for(int k=; k<; ++k)
for(int i=; i<N; ++i)
dp[i][k]=dp[dp[i][k-]][k-];
while(m--) {
int l,r;
scanf("%d%d",&l,&r);
int ans=;
for(int k=; k>=; --k)
if(dp[l][k]<r)ans^=(<<k),l=dp[l][k];
printf("%d\n",dp[l][]<r?-:ans+);
}
return ;
}

最新文章

  1. STM32 复合设备编写
  2. Linux下不同机器之间拷贝文件
  3. 【实战Java高并发程序设计 5】让普通变量也享受原子操作
  4. IE10、IE11 ASP.Net 网站无法写入Cookie 问题
  5. How Google TestsSoftware - Part One
  6. JavaScript 图片的上传前预览(兼容所有浏览器)
  7. 腾讯新浪通过IP地址获取当前地理位置(省份)的接口
  8. JAVA7遍历文件夹
  9. [html] src与href的区别
  10. Django开发博客 入门篇
  11. HW2.16
  12. MVC中的UrlHelper
  13. 使用GDB调试器(一)
  14. javascript设计模式——中介者模式
  15. 吓尿了,mac下bash出了问题
  16. SpringBoot与Mybatis整合方式01(源码分析)
  17. 使用STS创建springboot项目pom.xml文件报错org.apache.maven.archiver.MavenArchiver.getManifest
  18. asp.net core 基于角色的认证登陆
  19. KMP算法——从入门到懵逼到了解
  20. pandas DataFrame(2)-行列索引及值的获取

热门文章

  1. MSSQL字符串分割
  2. RedisTemplate5种数据结构操作
  3. DOM事件练习 I
  4. CentOS7使用阿里云源安装Docker
  5. webdriervAPI(键盘事件)
  6. 使用PowerShell 自动创建DFS命名空间服务器
  7. Laravel 查询&amp;数据库&amp;模型
  8. [python] a little deep learning case
  9. [转帖]etcd 在超大规模数据场景下的性能优化
  10. idea - maven子工程找不到父工程pom