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