zoukankan      html  css  js  c++  java
  • 洛谷P1890 gcd区间 [2017年6月计划 数论09]

    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

    满足区间加法,询问远大于数据量,st表最快

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    
    const int MAXN = 1000 + 10;
    
    inline void read(long long& x)
    {
        x = 0;char ch = getchar();char c = ch;
        while(ch < '0' || ch > '9')c = ch, ch = getchar();
        while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
        if(c == '-')x = -x;
    }
    
    inline int min(long long a, long long b){return a > b ? a : b;}
    inline int max(long long a, long long b){return a > b ? b : a;}
    
    long long stlist[MAXN][30];
    long long num[MAXN];
    long long log2[MAXN]; 
    long long pow2[MAXN];
    long long n,m;
    
    inline int gcd(int a, int b)
    {
        if(a < b)
        {
            int tmp = a;
            a = b;
            b = tmp;
        }
        while(b)
        {
            int tmp = a % b;
            a = b;
            b = tmp;
        }
        return a;
    }
    
    void yuchuli()
    {
        int M = 0;
        while(pow2[M + 1] <= n)M ++;
        for(int i = 1;i <= M;i ++)
        {
            for(int j = n;j > 0;j --)
            {
                stlist[j][i] = stlist[j][i - 1];
                if(j + pow2[i - 1] <= n)stlist[j][i] = gcd(stlist[j + pow2[i - 1]][i - 1], stlist[j][i]);
            }
        }
    }
    
    int stfind(int l, int r)
    {
        int M = 0;
        while(pow2[M + 1] <= (r - l + 1))M ++;
        return gcd(stlist[l][M], stlist[r - pow2[M] + 1][M]);
    } 
    
    long long tmp1, tmp2;
    
    int main()
    {
        read(n);read(m);
        for(int i = 1;i <= n;i ++)
            read(stlist[i][0]);
        log2[0] = -1;
        for(int i = 1;i <= n;i ++)
            log2[i] = log2[i >> 1] + 1;
        pow2[0] = 1;
        for(int i = 1;i <= n;i ++)
            pow2[i] = pow2[i - 1] << 1;
        yuchuli();
        for(int i = 1;i <= m;i ++)
        {
            read(tmp1);read(tmp2);
            printf("%d
    ", stfind(tmp1, tmp2));
        }
        return 0;
    }
    
  • 相关阅读:
    Windows PE变形练手3-把通用模板机器码直接覆盖目标PE
    Windows PE变形练手2-开发一套自己的PE嵌入模板
    R3抹掉加载的DLL
    R3获取kernel32地址
    Windows PE变形练手1-用PE自己的机器码修改自己的逻辑
    Windows PE 第十三章 PE补丁技术
    Windows PE 第十二章 PE变形技术
    16.PHP_Ajax模拟服务器登录验证
    15.PHP_PHP与Ajax
    14.PHP_PHP与XML技术
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7072873.html
Copyright © 2011-2022 走看看