前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【题解】gcd区间(ST表)

【题解】gcd区间(ST表)

作者头像
fishhh
发布2022-08-31 15:05:48
6590
发布2022-08-31 15:05:48
举报
文章被收录于专栏:OI算法学习笔记OI算法学习笔记

题目描述

给定一行n个正整数a[1]…a[n]。

m次询问,每次询问给定一个区间[L,R],输出a[L]…a[R]的最大公因数。

输入格式

第一行两个整数n,m。

第二行n个整数表示a[1]…a[n]。

以下m行,每行2个整数表示询问区间的左右端点。

保证输入数据合法。

输出格式

共m行,每行表示一个询问的答案。

输入输出样例

输入 #1

代码语言:javascript
复制
5 3
4 12 3 6 7
1 3
2 3
5 5

输出 #1

代码语言:javascript
复制
1
3
7

说明/提示

题目分析

最大公约数的一个特点就是

那么

利用ST表,由区间最值修改为区间gcd的寻找。

代码实现

代码语言:javascript
复制
#include <iostream>
#include <cstdio>
using namespace std;
const int N=1e3+5;
int n,m;
int gcd(int a,int b){//辗转相除法求最大公约数
	while(b){
		int r=a%b;
		a=b;
		b=r;
	}
	return a;
}
int a[N];
int Log[N];//Log[x]=log2(x)
int st[N][N];//st[i][j]=gcd(i ~ i+(1<<j)-1) 
int main(){
	int n,m,l,r;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	//预处理 Log[] 数组
	Log[1]=0,Log[2]=1;
	for(int i=3;i<=n;i++){
		Log[i]=Log[i/2]+1;
	}
	
	//单个元素的最大公约数是自己
	for(int i=1;i<=n;i++){
		st[i][0]=a[i];
	}
	//预处理 ST表
	for(int j=1;(1<<j)<=n;j++){
		for(int i=1;i+((1<<j)-1)<=n;i++){
			st[i][j]=gcd(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}
	}
	while(m--){
		scanf("%d%d",&l,&r);
		int len=r-l+1;
		int Lg=Log[len];
		//求区间内的最大公约数
		printf("%d\n",gcd(st[l][Lg],st[r-(1<<Lg)+1][Lg]));
	}
	return 0;
}

Q.E.D.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题目描述
  • 输入格式
  • 输出格式
  • 输入输出样例
  • 说明/提示
  • 题目分析
  • 代码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档