CodeForces-1175E Minimal Segment Cover

Posted dsjkafdsaf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 \le R_i \le 5e5\)

\(0 \le X_i \le Y_i \le 5e5\)

Output

对于每个询问输出一个答案。

若无法覆盖,输出\(-1\)即可。

Sample Input

2 3
1 3
2 4
1 3
1 4
3 4
3 4
1 3
1 3
4 5
1 2
1 3
1 4
1 5

Sample Output

1
2
1
1
1
-1
-1

利用倍增维护线段覆盖到的区间。

首先,我们发现对于一个端点我们只用关心能覆盖它的线段最远能覆盖到哪里。

对于每个左端点处理出用同一条线段最远的右端点。

那么,覆盖的过程就是从左端点跳到最远的点,\(Ans++\),重复执行这个过程直到覆盖到右端点。

如果暴力模拟,每次从一个段点跳到另一个端点,时间复杂度\(O(n)\)

仔细想想,我们发现这个过程和\(LCA\)的过程很像,于是我们就可以用倍增维护了。

\(Fa[i][j]\) 表示用\(1<<j\)条线段,从\(i\)开始最远能覆盖到的点。

代码如下

#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <iostream>
#include <algorithm>

using namespace std;

#define int long long
#define u64 unsigned long long
#define Raed Read
#define reg register
#define debug(x) cerr<<#x<<" = "<<x<<endl;
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define erep(i,G,x) for(reg int i=(G).Head[x]; i; i=(G).Nxt[i])

inline int Read() 
    int res = 0, f = 1;
    char c;
    while (c = getchar(), c < 48 || c > 57)if (c == '-')f = 0;
    do res = (res << 3) + (res << 1) + (c ^ 48);
    while (c = getchar(), c >= 48 && c <= 57);
    return f ? res : -res;


template<class T>inline bool Min(T &a, T const&b) 
    return a > b ? a = b, 1 : 0;

template<class T>inline bool Max(T &a, T const&b) 
    return a < b ? a = b, 1 : 0;


const int N = 2e5 + 5, M = 5e5 + 5, mod = 1e6 + 7;
const int dx[5] = 1, -1, 0, 0, 0, dy[5] = 0, 0, 0, 1, -1;
const  double eps = 1e-6;

int Fa[M][20], R[M];

inline void _main(void) 
    int n = Read(), m = Raed();
    rep(i, 1, n) 
        int x = Raed(), y = Read();
        Max(R[x], y);
    
    Fa[0][0] = R[0];
    rep(i, 1, M - 5)Max(R[i], R[i - 1]), Fa[i][0] = R[i];
    rep(j, 1, 19)rep(i, 0, M - 5)Fa[i][j] = Fa[Fa[i][j - 1]][j - 1];
    while (m--) 
        int Ans = 0, l = Raed(), r = Raed();
        drep(i, 19, 0)if (Fa[l][i] < r)l = Fa[l][i], Ans |= 1 << i;
        l = Fa[l][0];
        if (l < r)Ans = -1;
        else Ans++;
        printf("%d\n", Ans);
    


signed main() 
#define offline1
#ifdef offline
    freopen(".in", "r", stdin);
    freopen(".out", "w", stdout);
    _main();
    fclose(stdin); fclose(stdout);
#else
    _main();
#endif
    return 0;

以上是关于CodeForces-1175E Minimal Segment Cover的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 1175E 倍增

CodeForces - 1175B Catch Overflow!(栈模拟多重for循环)

codeforces 1175 D. Array Splitting

Codeforces 1175F 尺取法 性质分析

CF-825E Minimal Labels (反向拓扑)

[CF825E] Minimal Labels(反向建图,拓扑排序)