CodeForces-1175E最小セグメントカバー

タイトル説明

既存の\(N- \)線分、左右のエンドポイントの各セグメント\(L_iを、R_iを\)を確実にするために、\(L_iを\ルR_iを\)を

そこ\(m個\)クエリ、各クエリ\(X_I、Y_I \)必要最小限のライン間隔により覆わすべての点。

入力

最初の行の入力は、2つの整数を含む\(N、M \) 意味は上記に示しました。

次に、ある(N \)\行は、各行は2つの整数を有します。

最初の\(I + 1 \)ラインが含まれている\を(2 \)の整数、それぞれ、\(L_iを、R_iを\)

\(m個\)ライン、示し\(m個\)質問THが。

\(1 \ nは、2E5の\ \ M)

(L_iを\ R_iと\ 5E5の\ \ 0)\

\(0 \ X_I \ Y_I \ 5E5 \)

出力

出力各照会のための答え。

あなたがカバーできない場合は、出力\(--1 \)することができます。

サンプル入力

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

サンプル出力

1
2
1
1
1
-1
-1

メンテナンスセグメント間隔をカバーするために乗算器を使用して。

まず、我々は唯一のエンドポイントのため、我々はどこへ行くカバーするケア・セグメント遠いとそれをカバーできることがわかりました。

各治療右点遠い同じセグメントと左端点について。

だから、プロセスは、最遠点をジャンプしてエンドポイントをカバーするために残っている\(ANS ++ \) 右のポイントにカバーされるまで、このプロセスを繰り返します。

暴力的なシミュレーションであれば、別のエンドポイントへの1つのセグメントからそれぞれのジャンプ、時間の複雑\(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;
}

おすすめ

転載: www.cnblogs.com/dsjkafdsaf/p/11259557.html