zoukankan      html  css  js  c++  java
  • 洛谷 P1890 gcd区间

    P1890 gcd区间
    题目提供者 洛谷OnlineJudge
    标签 数论(数学相关)
    难度 普及/提高-
    题目描述
    给定一行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

    /*
    区间型DP.
    o(n^2logn).
    用DP跑的原因是便于查询. 
    对于求gcd区间重叠是没问题的.
    这题也可以挂在线段树上跑.
    然后转移显然. 
    */
    #include<iostream>
    #include<cstdio> 
    #include<algorithm>
    #define MAXN 1001
    using namespace std;
    int f[MAXN][MAXN],n,m,x,y;
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=n;i++)  f[i][i]=read();
        for(int i=n;i>=1;i--)
         for(int j=i;j<=n;j++)
          {
            if(i==j) continue;
            f[i][j]=__gcd(f[i][j-1],f[i+1][j]);
          }
        while(m--)
          printf("%d
    ",f[x=read()][y=read()]);
        return 0;
    }
    /*
    o(nlogn+mlogn).
    因为线段树查询是log的.
    查询次数特别多.
    所以跑起来会慢一些. 
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define MAXN 10001
    using namespace std;
    int n,m,tot,cut,a[MAXN];
    struct data{int l,r,lc,rc,x;}tree[MAXN*4];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void build(int l,int r)
    {
        int k=++cut;
        tree[k].l=l,tree[k].r=r;
        if(l==r)
        {
            tree[k].x=read();a[++tot]=tree[k].x;return ;
        }
        int mid=(l+r)>>1;
        tree[k].lc=cut+1;
        build(l,mid);
        tree[k].rc=cut+1;
        build(mid+1,r);
        tree[k].x=__gcd(tree[tree[k].lc].x,tree[tree[k].rc].x);
    }
    int query(int k,int l,int r)
    {
        if(l<=tree[k].l&&tree[k].r<=r)
        {
            return tree[k].x;
        }
        int tot=a[l];
        int mid=(tree[k].l+tree[k].r)>>1;
        if(l<=mid) tot=__gcd(tot,query(tree[k].lc,l,r));
        if(r>mid) tot=__gcd(tot,query(tree[k].rc,l,r));
        return tot;
    }
    int main()
    {
        int x,y;
        n=read();m=read(); 
        build(1,n);
        while(m--)
        {
            x=read(),y=read();
            printf("%d
    ",query(1,x,y));
        }
        return 0;
    }
  • 相关阅读:
    2017 多校联合训练 8 题解
    2017 多校联合训练 7 题解
    2017 多校联合训练 6 题解
    2017 多校联合训练 5 题解
    2017 多校联合训练 4 题解
    windows 安装python
    pygame 使用
    python 发布
    面向对象的思维方法
    python 基础
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070748.html
Copyright © 2011-2022 走看看