P1890 GCD間隔セグメントツリー

タイトル説明

所与の行\(N- \)は正の整数\([1] .. [N-] \)

\(m個\)クエリ各時間間隔の所定の時間クエリ、\([L、R&LT] \) 出力\([L] .. [R] \) 最大公約数です。

入力形式

二つの整数の最初の行\(N、Mの\)

第n行の整数を表し([N] \ .. [1])\

以下\(Mの\)行、各行\(2 \)エンドポイント呼び掛け間隔について示す整数。

入力データが有効であることを確認してください。

出力フォーマット

CO mラインは、各ラインは、問い合わせに対する回答を表します。

サンプル入力と出力

入力#1

5 3
4 12 3 6 7
1 3
2 3
5 5

出力#1

1
3
7

説明/ヒント

データの30%、\(N - <= 100、M <= 10 \)

データの60%、\(M <= 1000 \)

データの100%に\(1 <= N - <= 1000,1 <= M <= 1,000,000 \)

 0 < 数字大小 <= 1,000,000,000

ソリューション:

ここに書かれたセグメントのツリー構造のポインタが提供されます。

この問題を解決するには、最初に知っておく必要があります\(GCDの\)ユークリッドアルゴリズムから見見つけるための方法を、:

int gcd(int x, int y) { return y == 0 ? x : gcd(y, x % y); }

第二に、\(GCD \)を満たすセクション加法、すなわち:
\ [GCD(L、R&LT)がGCD(GCD(L、K)、GCD(K + 1、R&LT))、[L、R&LTにおけるK \を= ] \]
セグメントツリーのメンテナンスは、直接することができ...

コード:

#include <iostream>
#include <cstdio>
using namespace std;
int read() {
    int x = 0, f = 1; char ch;
    while(! isdigit(ch = getchar())) (ch == '-') && (f = -f);
    for(x = ch^48; isdigit(ch = getchar()); x = (x<<3) + (x<<1) + (ch^48));
    return x * f;
}
int n, m;
inline int gcdd(int x, int y) { return y == 0 ? x : gcdd(y, x % y); }
struct Segment {
    struct node {
        int l, r, gc;
        node* ch[2];
        node(int l, int r, int gc) : l(l), r(r), gc(gc) {}
        inline int mid() { return (l + r) >> 1; }
        inline void up() { gc = gcdd(ch[0]->gc, ch[1]->gc); }
    } *root;
    void build(node *&o, int l, int r) {
        o = new node (l, r, 0);
        if(l == r) { o->gc = read(); return; }
        build(o->ch[0], l, o->mid());
        build(o->ch[1], o->mid()+1, r);
        o->up();
    }
    int query(node *o, int l, int r) {
        if(l <= o->l && o->r <= r) return o->gc;
        int res = 0;
        if(o->mid() >= l) res = query(o->ch[0], l, r);
        if(o->mid() < r) res = gcdd(res, query(o->ch[1], l, r));
        return res;
    }
} tr;
int main() {
    n = read(); m = read();
    tr.build(tr.root, 1, n);
    for(int i = 1, l, r; i <= m; ++ i) {
        l = read(); r =  read();
        printf("%d\n", tr.query(tr.root, l, r));
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/Paranoid-LS/p/11582701.html