洛谷P1890 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
分析:如果只求一个区间,我们只需要扫一边就过了,但是要问的区间个数太多,就必须要预处理出区间的信息,f[i][j]表示[i,j]的gcd,每次添加一个元素就用当前区间的gcd和这个元素求gcd,答案用来区间并的f值,最后用O(1)输出就好了.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int n, m,a[1010],dp[1010][1010];

int gcd(int a, int b)
{
    if (!b)
        return a;
     return gcd(b, a % b);
}

int main()
{
    scanf("%d%d", &n,&m);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        dp[i][i] = a[i];
    }
    for (int i = 1; i <= n; i++)
        for (int j = i; j < n; j++)
        dp[i][j + 1] = gcd(dp[i][j], a[j + 1]);
    for (int i = 1; i <= m; i++)
    {
        int l, r;
        scanf("%d%d", &l, &r);
        printf("%d\n", dp[l][r]);
    }

    return 0;
}

 

 
posted @ 2017-09-08 17:58 zbtrs 阅读(...) 评论(...) 编辑 收藏