我是靠谱客的博主 缓慢面包,最近开发中收集的这篇文章主要介绍C++ 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

题目地址: https://www.luogu.org/problemnew/show/P1890


个人思路:

  • 一开始打了个枚举获取答案的代码,虽然开了inline,并使用了scanf,但还是TLE了最后两个点.
  • 之后又尝试使用一个data[]数组,记忆化已经gcd得到的答案,仍然TLE,
  • 想了一下,只好看题解.题解的方法是预处理,然后O(1)查询.
  • 然后就自己思考了一下,之前也想过预处理,但是感觉复杂度可能太高了.
  • 但是题解中的预处理使用了gcd的一个传递性.假设我们要预处理的是a[i],则预处理存储数组data[i][j]=gcd(data[i][j-1])(因为j代表区间长度,代表起始点.然后通过最大公约数的性质即可求出答案)
  • 再思考一下时间复杂度,大约为O(n^2),又因为n的范围够小,所以这个时间复杂度可以接受.

#include<cstdio>
#include<iostream>
using namespace std;
int a[1000],data[1005][1005];
inline int gcd(int a,int b){
if(a<b)swap(a,b);;
if(b==0)return a;
return gcd(b,a%b);
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
data[i][j]=gcd(data[i][j-1],a[j]);
}
}
for(int i=1;i<=m;i++){
int ta,tb;
scanf("%d%d",&ta,&tb);
printf("%dn",data[ta][tb]);
}
return 0;
}

 

最后

以上就是缓慢面包为你收集整理的C++ P1890 gcd区间的全部内容,希望文章能够帮你解决C++ P1890 gcd区间所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部