zoukankan      html  css  js  c++  java
  • 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
    ", 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;
    }
    
  • 相关阅读:
    iphone备忘录存储路径
    wp7常用Task,启动器与选择器
    sql ce 修改表数据
    MessageBox.Show()中的换行
    莫名异常
    wp7中设置toolkit的工具栏图标不能正常显示(DatePicker和TimePicker)
    json 解析
    wp7弹出提示框退出程序
    第一个ios程序
    TextBox只显示数字
  • 原文地址:https://www.cnblogs.com/dsjkafdsaf/p/11259557.html
Copyright © 2011-2022 走看看