数字の与えられた範囲内で問題の解決策を見つけるための演習10の数の半分

タイトル説明

今、あなたの長伝える\(N \)を順序付けられた配列の\(A_1、A_2、...、A_N \) および\(q個の\は)一度、必ずあなたに2つの数値を与える尋ね尋ねX_1(\ \)\(X_2 \)各照会のために、あなたは配列の出会いを決定する必要があります\(X_1 \ルa_iを\ル X_2 \) の要素(a_iを\)\の番号。

入力形式

入力整数の最初のラインを含む\(N-(1 \ N-LE \ル100000)\)配列表現の要素数のために、。
第二行は、入力含有\(\ N-)の整数、表すために使用される配列の要素のそれぞれの二つの間の空間が存在する\(A_1、A_2、...、 A_N(1 \ルa_iを\ル10 ^ 9 そしてA_1 \ルA_2 \ル... \ルA_N)\)
入力の3行目は、整数含ま\(Q(1 \ルQ \ 100000ル)\)問い合わせの数を示すために、。
\(Q \)行、2つの整数を含む各行\(X_1、X_2(1 \ルX_1 \ルX_2 \ル^ 10 9)\) 問い合わせされる数を示します。

出力フォーマット

各クエリのための\(X_1、X_2 \) 出力配列満足\(X_1 \ルa_iを\ル X_2 \) 要素\(a_iを\)数。別々の行に各出力。

サンプル入力

5
1 3 5 7 9
3
3 6
2 100
11 13

サンプル出力

2
4
0

トピック分析

この質問は一見トラブルのビットですが、実際にも、解決するために、バイナリのアルゴリズムを使用することができます。
しかし、ここで我々は、二半分各プロンプトを使用する必要があります\(X_1、X_2を\) 我々はする必要があります。

  • 見出さバイナリ\(\ルX_1 \)は、最小の要素の座標\(I_1 \)
  • 二値のfind \(\ GEのX_2の\は)の最大の要素座標\(I_2が使用されますが\)

だから、\(I_2-I_1 + 1 \は ) 私たちの答えです。
次のようにコードは次のとおりです。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int n, q, x1, x2, a[maxn];
int solve() {
    int L = 1, R = n, i1 = -1, i2 = -1;
    while (L <= R) {    // 查找>=x1的最小坐标i1
        int mid = (L + R) / 2;
        if (a[mid] >= x1) {
            i1 = mid;
            R = mid - 1;
        }
        else L = mid + 1;
    }
    L = 1; R = n;
    while (L <= R) {    // 查找<=x2的最大坐标i2
        int mid = (L + R) / 2;
        if (a[mid] <= x2) {
            i2 = mid;
            L = mid + 1;
        }
        else R = mid - 1;
    }
    if (i1 == -1 || i2 == -1) return 0;
    return i2 - i1 + 1;
}
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    cin >> q;
    while (q --) {
        cin >> x1 >> x2;
        cout << solve() << endl;
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/zifeiynoip/p/11450641.html