codeforce 1175E Minimal Segment Cover ST表 倍增思想

这题太巧妙了。

题意是,给定2*10^5个区间。然后2*10^5组询问,每次询问一个区间,问至少需要几个给定区间,才能将其完全覆盖。坐标范围5*10^5。

如果只有一个询问区间,是经典的贪心问题。我们每次选择,尽可能覆盖的靠右的区间。

但是这题显然贪心的话,时间是不够的。

考虑使用倍增进行预处理。

我们用dp[i][o]表示从i点开始,选择o个区间,能覆盖到最远哪个点。为-1,则表示不存在。

那么显然如果dp[i][o - 1] != -1 时,dp[i][o] = dp[dp[i][o - 1]][o - 1]。否则为-1。

那么我么如何求出dp[i][0]呢?读入的时候,dp[tx][0] = max(dp[tx][0],ty)。然后从1到5*10^5,满足dp[i - 1][0]包括i点的条件下,递推下即可,dp[i][0] = max(dp[i][0],dp[i - 1][0])。

考虑查询询问。

类似倍增LCA,我们从大到小,试着跳,跳到或跳过,就不跳,以此避免跳多浪费。最后一定跟右端点只差一步,答案+1,即可。

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 int ans,n,m;
 7 int dp[500010][20];
 8 int main()
 9 {
10     memset(dp,-1,sizeof(dp));
11     scanf("%d%d",&n,&m);
12     int tl,tr;
13     for (int i = 1;i <= n;i++)
14     {
15         scanf("%d%d",&tl,&tr);
16         dp[tl][0] = max(dp[tl][0],tr);
17     }
18     for (int i = 1;i <= 500000;i++)
19         if (dp[i - 1][0] >= i && dp[i - 1][0] > dp[i][0])
20             dp[i][0] = dp[i - 1][0];
21     int t = log2(500000);
22     for (int o = 1;o <= t;o++)
23     {
24         for (int i = 0;i <= 500000;i++)
25         {
26             if (dp[i][o - 1] == -1)
27                 continue;
28             dp[i][o] = dp[dp[i][o - 1]][o - 1];
29         }
30     }
31     for (;m;m--)
32     {
33         ans = 0;
34         scanf("%d%d",&tl,&tr);
35         for (int o = t;o >= 0;o--)
36         {
37             if (dp[tl][o] < tr && dp[tl][o] != -1)
38             {
39                 ans += (1 << o);
40                 tl = dp[tl][o];
41             }
42         }
43         if (dp[tl][0] >= tr)
44             printf("%d\n",ans + 1);
45         else
46             printf("-1\n");
47     }
48     return 0;
49 }

原文地址:https://www.cnblogs.com/iat14/p/11620211.html

时间: 2024-11-02 01:41:25

codeforce 1175E Minimal Segment Cover ST表 倍增思想的相关文章

51nod2621 树上距离一题四解ST表+倍增+Tarjan+树剖

LCA裸题 只有代码无原理,给自己复习用 1. ST表(这题2^10就够了) 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=2e3+50; 5 6 int cnt,dfn[maxn],dep[maxn],dp[maxn][21],lg2[maxn],dis[maxn],w[maxn][maxn]; 7 std::vector<int> G[maxn]; 8 void dfs(int u,in

CF1175E Minimal Segment Cover 题解

题意:给出\(n\)个形如\([l,r]\)的线段.\(m\)次询问,每次询问区间\([x,y]\),问至少选出几条线段,使得区间\([x,y]\)的任何一个部位都被至少一条线段覆盖. 首先有一个显然的贪心,设询问区间为\([l,r]\),则所取的区间最靠左的一个的左端点必定小于等于\(l\),并且要使这个区间尽可能地向右延伸. 取完第一个之后,重复以上的贪心,直至满足条件,那么这样的答案必定是最小的. 但是这样的时间复杂度是\(O(nm)\)的,所以要考虑优化,优化方法是用倍增,每次向右跳\(

CodeForces-1175E Minimal Segment Cover

题目描述 现有\(n\)条线段,每条线段的左右端点为\(L_i,R_i\),保证\(L_i \le R_i\). 有\(m\)个询问,每次查询\(X_i,Y_i\)区间内所有点被覆盖所需的线段的最小值. Input 输入第一行包含两个整数\(n,m\),含义如上所述. 接下来,有\(n\)行,每行有两个整数. 第\(i+1\)行包含\(2\)个整数,分别表示\(L_i,R_i\) . 接下来\(m\)行,表示\(m\)个询问. \(1 \le n,m \le 2e5\) \(0 \le L_i

CF1175E Minimal Segment Cover

题目链接 题意 给出n条线段.m次询问,每次询问给出一个区间\([l,r]\)问最少需要多少条线段才能覆盖区间\([l,r]\). 所有坐标\(\le 5\times 10^5\).\(n,m\le 2\times 10^ 5\) 思路 其实是比较经典的线段覆盖问题. \(f[i][j]\)表示从i开始走\(2^j\)条线段最远到达的位置. 然后对于每次询问都走一遍即可. 代码 /* * @Author: wxyww * @Date: 2019-06-06 10:55:48 * @Last Mo

倍增思想到ST表RMQ

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 36864   Accepted: 17263 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer Joh

【倍增】RMQ的ST表算法

RMQ问题:给定一个长度为N的区间,M个询问,每次询问Li到Ri这段区间元素的最大值/最小值. RMQ的高级写法一般有两种,即为线段树和ST表. 本文主要讲解一下ST表的写法.(以区间最大值为例) ST表:一种利用dp求解区间最值的倍增算法. 定义:f[i][j]表示i到i+2^j-1这段区间的最大值. 预处理:f[i][0]=a[i].即i到i区间的最大值就是a[i]. 状态转移:将f[i][j]平均分成两段,一段为f[i][j-1],另一段为f[i+2^(j-1)][j-1]. 两段的长度均

hdu6107 倍增法st表

发现lca的倍增解法和st表差不多..原理都是一样的 /* 整篇文章分成两部分,中间没有图片的部分,中间有图片的部分 分别用ST表求f1,f2表示以第i个单词开始,连续1<<j行能写多少单词 */ #include<bits/stdc++.h> #define FIN freopen("in.txt","r",stdin); using namespace std; #define ll long long #define MX 100005

CF1190E Tokitsukaze and Explosion 二分、贪心、倍增、ST表

传送门 最小值最大考虑二分答案,不难发现当最小值\(mid\)确定之后,原点到所有直线的距离一定都是\(mid\)时才是最优的,也就是说这些直线一定都是\(x^2+y^2=mid^2\)的切线. 接下来考虑一个点会被哪些切线所保护.作出这个点到圆的公切线,得到两个切点,那么在这两个切点之间的优弧上选择一个点,以它为切点的切线就可以保护当前点.也就是说能够保护一个点的切线的切点在圆上表现为一段角度的区间.可以用解析几何计算出这个角度的区间. 接下来需要在\([-\pi , \pi]\)上选择不超过

[模板]ST表浅析

ST表,稀疏表,用于求解经典的RMQ问题.即区间最值问题. Problem: 给定n个数和q个询问,对于给定的每个询问有l,r,求区间[l,r]的最大值.. Solution: 主要思想是倍增和区间dp. 状态:dp[i][j] 为闭区间[i,i+2^j-1]的最值. 这个状态与转移方程的关系很大,即闭区间的范围涉及到了转移方程的简便性. 转移方程:dp[i][j]=max(dp[i][j-1],dp[i+2^(j-1)][j-1]). 这是显然的,但这里有个细节:第一个项的范围为[i,i+2^