[洛谷1890]gcd区间

题目描述

给定一行n个正整数a[1]..a[n]。
m次询问,每次询问给定一个区间[L,R],输出a[L]..a[R]的最大公因数。

输入输出格式

输入格式:

第一行两个整数n,m。
第二行n个整数表示a[1]..a[n]。
以下m行,每行2个整数表示询问区间的左右端点。
保证输入数据合法。

输出格式:

共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就是自己;如果区间内是相邻的两个数,就可以用扩展欧几里德定理;如果区间是不相邻的两个数,那么f[i,j]:=gcd(f[i-1,j],a[j])。然后线上询问处理,时间复杂度O(n^2).

var f:array[1..1000,1..1000] of longint;  
    a:array[1..1000] of longint;  
    i,j,n,m,x,y:longint;  
  
function gcd(x,y:longint):longint;  
begin  
    if y=0 then  
        begin  
            gcd:=x;  
            exit;  
        end;  
    gcd:=gcd(y,x mod y);  
end;  
  
begin  
    fillchar(f,sizeof(f),0);  
    readln(n,m);  
    for i:=1 to n do read(a[i]);  
    for i:=1 to n do f[i,i]:=a[i];  
    for i:=1 to n do  
        for j:=i+1 to n do  
            begin  
                if j-i=1 then f[i,j]:=gcd(a[i],a[j])  
                else f[i,j]:=gcd(a[j],f[i,j-1]);  
            end;  
    for i:=1 to m do  
        begin  
            readln(x,y);  
            writeln(f[x,y]);  
        end;  
end.  
原文地址:https://www.cnblogs.com/yangqingli/p/4741174.html