HDOJ 5726 GCD 二分+ST表

原创 2016年08月28日 18:33:12

HDOJ 5726

题意:给定区间【L,R】求出区间【L,R】内数组中的数的GCD,并且找出所有的数对L0,R0,1<=L0<R0<=n,使得区间【L0,R0】内的GCD等于前一个GCD值


看到这个题,跟codeforces 689 D似曾相识啊!所以把两个题都一起补了

题解统一写在这儿吧

首先说做法:

ST表:用O(nlogn)的离线处理好任意区间的内的GCD值,然后做到O(1)的查询

ST表的搞法是典型的二分想法

拿最小值举例,我们要求某一段区间的最小值

可以把区间二分,先求左边区间的最小值,右边区间的最小值

那么整段区间的最小值就是上述两个值的较小值

因为GCD,MAX,MIN,LCM等都有这个性质,那么我们都可以用ST表来这样进行处理

然后呢,枚举左端点,用二分找到右端点,然后判断GCD值是否相等

然后把值统计到GCD的hash之中


为什么可以这么样做?!

因为:GCD,MAX,MIN,LCM等都是不增函数


也就是说,我们可以利用这个性质,使用ST表和二分来避免时间和空间上浪费

这个题呢,因为g值并不多,所以可以提前都给预处理好,建立一个mp的映射

codeforces 689D呢

因为不好预处理,所以涉及到两次二分的问题

第一次二分,找到右端点的左值(如果有的话)

如果有,那么进行第二次二分,找到右端点的右值,那么对应该左端点,答案的增长是右端点的区间长度

如果没有,那么说明对应该左端点,没有符合条件的右端点


代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+50; 
int a[maxn][20],T,n,m;
map<int,long long> mp;

int gcd(int x,int y){
	return y==0?x:gcd(y,x%y);
}

void init(){
	for(int j=1;(1<<j)<=n;j++)
		for(int i=1;i+(1<<j)-1<=n;i++)
			a[i][j]=gcd(a[i][j-1],a[i+(1<<(j-1))][j-1]);
}

int GETGCD(int L,int R){
	int K=(int)log2((double)(1.0*(R-L+1)));
	return gcd(a[L][K],a[R-(1<<K)+1][K]);
}

void getans(){
	mp.clear();
	int l,r,g,i,j,mid;
	for(i=1;i<=n;i++){
		g=a[i][0];
		j=i;
		while(j<=n){
			l=j,r=n;
			while(l<r){
				mid=(l+r+1)>>1;
				if (GETGCD(i,mid)==g) l=mid;
				else r=mid-1;
			}
			mp[g]+=(l-j+1);
			j=l+1;
			g=GETGCD(i,j);
		}
	}
}

int main(){
	//freopen("input.txt","r",stdin);
	scanf("%d",&T);
	for(int Case=1;Case<=T;Case++){
		scanf("%d",&n);
		for(int i=1;i<=n;i++) scanf("%d",&a[i][0]);
		init();
		getans();
		printf("Case #%d:\n",Case);
		scanf("%d",&m);
		int l,r,g;
		while(m--){
			scanf("%d%d",&l,&r);
			g=GETGCD(l,r);
			printf("%d %I64d\n",g,mp[g]);
		}
	}
	return 0;
}


HDU 5726 GCD [ST表+暴力二分]【数据结构|杂类】

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 ———————————————————————–. GCDTime Limit: 10000...
  • qq_33184171
  • qq_33184171
  • 2017年01月24日 17:26
  • 179

HDU 5726 GCD(RMQ+二分,详解,ST算法)

题目链接:HDU 5726 题面: GCD Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja...
  • David_Jett
  • David_Jett
  • 2016年07月20日 16:58
  • 1082

GCD (ST表,二分求区间查询)

HUD 5726 GCD    给一个序列,多次查询区间的最大公约数,并求出同样是这个最大公约数的区间有多少个。 区间查询采用ST表,第二问查询利用区间向右延伸最大公约数递减的规律可通过二分快速找到右...
  • yhn19951008
  • yhn19951008
  • 2016年07月22日 20:30
  • 280

HDU 5726 GCD 【GCD】【ST表+二分】【线段树+暴力枚举】

题意给一串数列,求区间GCD和整个数列中与该区间GCD相等的区间数分析首先区间GCD易求,用能求RMQ的方法都可以,比如ST表、线段树。关键是如何求第二个问题,这里有两种做法: 方法一 利用GCD...
  • DrCarl
  • DrCarl
  • 2017年01月17日 19:35
  • 134

【HDOJ 4768】 Flyer (等差数列+二分)

【HDOJ 4768】 Flyer (等差数列+二分) Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/...
  • ChallengerRumble
  • ChallengerRumble
  • 2015年09月07日 13:22
  • 1102

HDU 5726 GCD(RMQ+二分)(线段树也可)

hdu 5726 GCD
  • CerberuX
  • CerberuX
  • 2016年07月20日 16:27
  • 358

[HDU 5726] GCD (倍增法+二分)

HDU - 5726 给定一个序列,每次询问一个区间 输出这个区间上所有数的GCD,以及GCD与其相同的区间个数 赛上太智障了读错了题,以为是求得是GCD相同的子区间的个数一个连续区间的GC...
  • u012015746
  • u012015746
  • 2016年07月19日 19:25
  • 1756

RMQ--ST表算法理解

RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j ST算法(Sparse Tabl...
  • qq1169091731
  • qq1169091731
  • 2016年07月21日 11:59
  • 1091

数据结构_ST算法+二分搜索_GCD问题

区间GCD问题,一般指:给出一序列正整数数,每次询问一个整数K,求GCD等于K的范围有多少个。 HDU 5726...
  • LonerIt
  • LonerIt
  • 2016年10月07日 15:06
  • 251

【HDU 5726】GCD(映射+RMQ)

【HDU 5726】GCD(映射+RMQ) GCD Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536...
  • ChallengerRumble
  • ChallengerRumble
  • 2016年07月20日 18:29
  • 2440
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDOJ 5726 GCD 二分+ST表
举报原因:
原因补充:

(最多只允许输入30个字)