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 Modified time: 2019-06-06 14:54:02
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 1000000 + 100,logN = 23;
ll read() {
    ll x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') {
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9') {
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
int f[N][logN + 1];
int query(int l,int r) {
    ll ans = 0;
    for(int i = logN - 1;i >= 0;--i) {
        if(f[l][i] < r) {
            l = f[l][i];
            ans += (1 << i);
        }
    }
    l = f[l][0];ans++;
    if(l < r) return -1;
    return ans;

}
int main() {
    int n = read(),m = read();
    int mx = 0;
    for(int i = 1;i <= n;++i) {
        int l = read() + 1,r = read() + 1;
        f[l][0] = max(f[l][0],r);
        mx = max(mx,r);
    }

    for(int i = 1;i <= mx;++i) f[i][0] = max(f[i][0],max(i,f[i - 1][0]));

    for(int j = 1;j < logN;++j)
        for(int i = 1;i <= mx;++i)
            f[i][j] = f[f[i][j - 1]][j - 1];

    while(m--) {
        int l = read() + 1,r = read() + 1;
        printf("%d\n",query(l,r));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/wxyww/p/CF1175E.html

时间: 2024-10-06 00:22:00

CF1175E Minimal Segment Cover的相关文章

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

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

Educational Codeforces Round 66 (Rated for Div. 2)

a题教育我:不手写2个测试用例,就不要写代码,谢谢. b题真的恶心,判断溢出自己之前从没思考过的问题.最后用了很尴尬的判断,a=b+c的时候,三个数不能>=(1<<32),不能小于0,不知道为什么,也不想知道. c题是思维gap的味道,也靠推导能力,看你有没有思维jump的能力.用到了我特别喜欢的一种思考模式:设想答案长什么样子.答案肯定是中点离着两边一样远,才能最小化d(k),然后这个区间必然是覆盖了k个点,所以排序后固定长度的滑窗走起- d题.原来每次打比赛之前,我都在本子上手写两条

Codeforces Edu Round 66 A-E

A. From Hero to Zero 通过取余快速运行第一步即可.由于\(a \% b (a >= b) <= \frac{a}{2}\).所以总复杂度不超过\(O(log_2n)\). #include <cstdio> #include <iostream> using namespace std; typedef long long LL; int main(){ int T; scanf("%d", &T); while(T--)

uva 10020 Minimal coverage 【贪心】+【区间完全覆盖】

Minimal coverage The Problem Given several segments of line (int the X axis) with coordinates [Li,Ri]. You are to choose the minimal amount of them, such they would completely cover the segment [0,M]. The Input The first line is the number of test ca

UVA 10020 - Minimal coverage 解题心得

原题: The Problem Given several segments of line (int the X axis) with coordinates [Li,Ri]. You are to choose the minimal amount of them, such they would completely cover the segment [0,M]. The Input The first line is the number of test cases, followed

UVa 10020 - Minimal coverage(区间覆盖并贪心)

Given several segments of line (int the X axis) with coordinates [Li, Ri]. You are to choose the minimal amount of them, such they would completely cover the segment [0, M].InputThe first line is the number of test cases, followed by a blank line.Eac

【区间覆盖问题】uva 10020 - Minimal coverage

可以说是区间覆盖问题的例题... Note: 区间包含+排序扫描: 要求覆盖区间[s, t]; 1.把各区间按照Left从小到大排序,如果区间1的起点大于s,则无解(因为其他区间的左起点更大):否则选择起点在s的最长区间; 2.选择区间[li, ri]后,新的起点应更新为ri,并且忽略所有区间在ri之前的部分:  Minimal coverage  The Problem Given several segments of line (int the X axis) with coordinat