首页 > 其他分享 >[题解]CF1175E Minimal Segment Cover

[题解]CF1175E Minimal Segment Cover

时间:2024-06-24 12:34:02浏览次数:3  
标签:int 题解 线段 更新 CF1175E max Segment 我们 dp

思路

这是一道简单的 DP 题,DP 题的核心就是状态转移。

先来说一说 \(dp\) 数组的含义。

\(dp_{i,j}\) 表示从 \(i\) 这个点用 \(2 ^ j\) 条线段能走到的最远的点。

我们再来考虑一下边界情况。

因为我们只用 \(2 ^ 0\) 条线段,那么:\(dp_{i,0} = \max(dp_{i,0},r)\)

接着,我们递推一遍,从前往后更新一遍最大值。

即:\(dp_{i,0} = \max(dp_{i,0},dp_{i - 1,0})\)

然后我们对 \(dp\) 数组进行递增。

即:\(dp_{j,i} = dp_{dp_{j,i - 1},i - 1}\)

注:以上递推和递增的操作都需要从 \(1\) 到 \(N\),原因是:我们操作都是预处理,最后直接求答案的。

最后,我们直接用一个循环来求出答案。

如果 \(dp_{x,i} < y\),那么我们的结果直接加上 \(2 ^ i\),将 \(x\) 更新为 \(dp_{x,i}\)。

结果要加上 \(2 ^ i\) 的原因是:我们从 \(dp\) 数组的含义出发,我们需要的线段数量便是 \(2 ^ i\)

将 \(x\) 更新成 \(dp_{x,i}\) 的原因是:我们把点 \(x\) 之前的所有点都走过了,所以我们直接更新即可

我们最后算出来的结果是终点的上一个点,所以我们需要判断一下最后一个是否有解就行了,如果有解输出结果 + 1,否则输出 -1

Code

#include <bits/stdc++.h>  
  
using namespace std;  
  
const int N = 5e5 + 10;  
int n,m;  
int dp[N + 100000/*要开大一点,不然越界*/][25];  
  
int main(){  
    cin >> n >> m;  
    for (int i = 1;i <= n;i++){  
        int a,b;  
        cin >> a >> b;  
        dp[a][0] = max(dp[a][0],b);  
    }  
    for (int i = 1;i <= N;i++) dp[i][0] = max(dp[i][0],dp[i - 1][0]);  
    for (int i = 1;i <= 19;i++){  
        for (int j = 0;j <= N;j++){  
            dp[j][i] = dp[dp[j][i - 1]][i - 1];  
        }  
    }  
    while (m--){  
        int x,y;  
        int res = 0;  
        cin >> x >> y;  
        for (int i = 19;i >= 0;i--){  
            if (dp[x][i] < y){  
                res += (1 << i);  
                x = dp[x][i];  
            }  
        }  
        if (dp[x][0] >= y) cout << res + 1 << endl;  
        else puts("-1");  
    }  
    return 0;  
}  

标签:int,题解,线段,更新,CF1175E,max,Segment,我们,dp
From: https://www.cnblogs.com/WaterSun/p/18264792

相关文章

  • [题解]CF1092D1 Great Vova Wall (Version 1)
    思路发现,如果相邻元素的奇偶性相同,那么一定能通过在较低的位置竖着放若干个如果在\(i\)的位置竖着放一块砖头,使得这两列的高度相同。那么,我们想到直接考虑\(h_i\)的奇偶性,即将\(h_i\leftarrowh_i\bmod2\)。如果\(h_i=h_{i+1}\),我们显然可以同时使\(h_i\)和\(h......
  • [题解]CF1070C Cloud Computing
    思路考虑用线段树维护区间信息:价格在\([l,r]\)之间的CPU的数量。购买所有价格在\([l,r]\)之间CPU所需的钱。容易将区间修改转化为差分,从而实现单点修改。于是可以使用\(n\)个vector存储第\(i\)天所需进行的修改。查询第\(i\)天的答案时,如果不足\(k\)......
  • [题解]CF1746B Rebellion
    思路首先我们需要看到题目一个特殊的地方:这个序列中只存在\(0\)和\(1\)。那么,我们不难发现最终的答案一定是形如下面的序列:\(0,\dots,0,1,\dots,1\)。知道了这些,就很好想了。我们从后往前枚举,如果当前一位为\(0\)了,就从\(last\simi\)扫一遍,如果有\(1\)将最靠前的\(......
  • [题解]CF1742G Orray
    思路做这道题之前,首先要知道一个性质:\(a\operatorname{or}b\geqa\)。那么,我们就能得出一个结论:经过一定顺序的排列,最多经过\(\lceil\log_2^{a_{\max}}\rceil\)个数就能让前缀或的值达到最大值。我们不妨令有一个位置\(i\),\(b_1,b_2,\dots,b_{i-1}\)单调递增,而\(b_i......
  • [题解]CF1742E Scuza
    2022/11/23:修改了一下代码。题意有\(T\)组数据,每次给出一个\(n,q\),表示台阶的数量和询问的次数。然后再给出一个\(a_i\)为台阶高度的差分数组。每次询问给出一个\(k\),表示每次能走\(k\)个单位的高度。问:最高能到达的高度。思路考虑暴力,我们知道了高度的差分数组,那......
  • [题解]CF1741D Masha and a Beautiful Tree
    思路我们可以观察样例,不难发现:对于任意一段长度为\(2^k\)的区间中,如果最大值减最小值加\(1\)等于此区间的长度,那么一定有解。因为,我们的目标是使整个序列升序排列。因此,我们在一个区间内的最大值减最小值加\(1\)与区间长度是相等的。所以,我们可以用上述结论为判断无解的......
  • [题解]CF1741B Funny Permutation
    思路简单构造题,我们可以分为三种情况进行构造。\(n=3\)时,一定无解,输出-1。(你可以试试)\(n\bmod2=1\wedgen\neq3\)时,我们直接先输出\(n,n-1\),然后顺序输出即可。证明:令\(a\)为最后构造出的序列。那么,\(a_1=n,a_2=n-1,a_i=i-2(3\leqi\leq......
  • [题解]CF1732C2 Sheikh (Hard Version)
    思路首先证明一下当序列扩大时答案一定不劣。考虑\(f(l,r)\)到\(f(l,r+1)\)的变化。\[\begin{aligned}f(l,r)-f(l,r+1)&=s_{l,r}-xs_{l,r}-s_{l,r+1}+xs_{l,r+1}\\&=xs_{l,r+1}-xs_{l,r}-a_{r+1}\\&......
  • fdisk时WARNING: Re-reading the partition table failed with error 16: 设备或资源
    WARNING:Re-readingthepartitiontablefailedwitherror16:设备或资源现象:划分磁盘有警告, WARNING:Re-readingthepartitiontablefailedwitherror16:设备或资源忙.Thekernelstillusestheoldtable.Thenewtablewillbeusedatthenextrebootoraft......
  • P3974 [TJOI2015] 组合数学 题解
    Description给一个网格图,其中某些格子有一些财宝。每次从左上角出发,只能往右或下走,每一次经过一个格子至多只能捡走一块财宝,至少要走几次才可能把财宝全捡完?\(1\leqn\leq1000\),\(1\leqm\leq1000\),每个格子中的财宝不超过\(10^6\)块。Solution考虑把每个点\((i,j)\)......