Problem Description

Give you a sequence of N(N≤100,000) integers : a1,...,an(0<ai≤1000,000,000). There are Q(Q≤100,000) queries. For each query l,r you have to calculate gcd(al,,al+1,...,ar) and count the number of pairs(l′,r′)(1≤l<r≤N)such that gcd(al′,al′+1,...,ar′) equal gcd(al,al+1,...,ar).

Input

The first line of input contains a number T, which stands for the number of test cases you need to solve.

The first line of each case contains a number N, denoting the number of integers.
The second line contains N integers, a1,...,an(0<ai≤1000,000,000).
The third line contains a number Q, denoting the number of queries.
For the next Q lines, i-th line contains two number , stand for the li,ri, stand for the i-th queries.

Output

For each case, you need to output “Case #:t” at the beginning.(with quotes, t means the number of the test case, begin from 1).

For each query, you need to output the two numbers in a line. The first number stands for gcd(al,al+1,...,ar) and the second number stands for the number of pairs(l′,r′) such that gcd(al′,al′+1,...,ar′) equal gcd(al,al+1,...,ar).

Sample Input

1
5
1 2 4 6 7
4
1 5
2 4
3 4
4 4

Sample Output

Case #1:
1 8
2 4
2 4
6 1 

题意:

有N个数,求第L个数到第R个数的最大公约数,并且求出任意区间内最大公约数为ans的数量。

题解:

对于区间[L,R],如果L固定不变,R不断右移时,gcd的值在不断下降,而且每次下降的幅度都不小于一半。我们只要枚举左端点L,然后二分L到N的区间,找到最大公约数为gcd的最大区间,记录这个gcd的数量并更新到map中即可。

#include<iostream>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
const int MAX=;
int dp[MAX][];
int mm[MAX];
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} void initrmq(int n,int b[])
{
mm[]=-;
for(int i=;i<=n;i++)
{
mm[i]=((i&(i-))==)?mm[i-]+:mm[i-];
dp[i][]=b[i];
}
for(int j=;j<=mm[n];j++)
for(int i=;i+(<<j)-<=n;i++)
dp[i][j]=gcd(dp[i][j-],dp[i+(<<(j-))][j-]);
}
ll rmq(int x,int y)
{
int k=mm[y-x+];
return gcd(dp[x][k],dp[y-(<<k)+][k]);
} ll find(int l,int r)
{
int k=(int)log2((double)(r-l+));
return gcd(dp[l][k], dp[r-(<<k)+][k]);
} map<int,long long>ma;
int main()
{
ios::sync_with_stdio(false);
int T,n,ca=,i,j;
cin>>T;
while(T--)
{
ma.clear();
int b[MAX];
cin>>n;
for(i=;i<=n;i++)
cin>>b[i]; initrmq(n,b);
for(i=;i<=n;i++)
{
int I=i;
ll now=b[i];
while(I!=n+)
{
int preI=I,N=n;
while(I!=N)
{
int mid=(I+N)/+;
if(find(I,mid)==now)
I=mid;
else N=mid-;
}
ma[now]+=N-preI+1ll;
I++;
if(I!=n+)
now=gcd(now,b[I]);
}
}
cout<<"Case #"<<ca++<<":"<<endl;
int q;
cin>>q;
for(i=;i<=q;i++)
{
int l,r;
cin>>l>>r;
ll ans=rmq(l,r);
cout<<ans<<" "<<ma[ans]<<endl;
}
}
return ;
}

【HDOJ 5726】GCD(RMQ+二分)的更多相关文章

  1. HDU 5726 GCD (RMQ + 二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 给你n个数,q个询问,每个询问问你有多少对l r的gcd(a[l] , ... , a[r]) ...

  2. 2016 Multi-University Training Contest 1 GCD RMQ+二分(预处理)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 题意:有N(N <= 100,000),之后有Q(Q <= 100,000)个区间查询[ ...

  3. GCD (RMQ + 二分)

    RMQ存的是区间GCD,然后遍历 i: 1->n, 然后不断地对[i, R]区间进行二分求以i为起点的相同gcd的区间范围,慢慢缩减区间. #include<bits/stdc++.h&g ...

  4. hdu 5726 GCD 倍增+ 二分

    题目链接 给n个数, 定义一个运算f[l,r] = gcd(al, al+1,....ar). 然后给你m个询问, 每次询问给出l, r. 求出f[l, r]的值以及有多少对l', r' 使得f[l, ...

  5. HDU 5726 GCD (2016多校、二分、ST表处理区间GCD、数学)

    题目链接 题意 : 给出一个有 N 个数字的整数数列.给出 Q 个问询.每次问询给出一个区间.用 ( L.R ) 表示.要你统计这个整数数列所有的子区间中有多少个和 GCD( L ~ R ) 相等.输 ...

  6. HDU 5726 GCD 区间GCD=k的个数

    GCD Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submis ...

  7. *HDU3486 RMQ+二分

    Interviewe Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  8. hdu 5289 Assignment(2015多校第一场第2题)RMQ+二分(或者multiset模拟过程)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 题意:给你n个数和k,求有多少的区间使得区间内部任意两个数的差值小于k,输出符合要求的区间个数 ...

  9. hdu 3486 Interviewe (RMQ+二分)

    Interviewe Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  10. 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分

    原文地址:http://www.cnblogs.com/GXZlegend/p/6825389.html 题目描述 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一 ...

随机推荐

  1. js Array数组对象常见方法总结

    Array对象一般用来存储数据. 其常用的方法包括: 1.concat()方法 concat() 方法用于合并两个或多个数组.它不会更改现有数组,而是返回一个新数组. 例如: var arr1=[1, ...

  2. linux php多版本

    ecshop还非php5.2 解压 gzip -cd php-5.2.14-fpm-0.5.14.diff.gz | patch -d php-5.2.14 -p1 打上php-fpm补丁再安装php ...

  3. Java不带.classpath的svn项目下载,转成到eclipse中

    .classpath是Eclipse的工程文件,别人没有将工程的信息传到SVN库中,就检查不出.classpath文件,识别不了项目结构. 这种做法也是比较提倡的方法.SVN上只要有项目的源码信息就可 ...

  4. xise官方网站|xise最新版下载|-xise

    诠释: 1. 破解VIP登陆限制 2.去后门 (自查) 下载地址 :https://pan.baidu.com/s/1eR2rUOM 查毒地址:http://a.virscan.org/a3983f3 ...

  5. DFS BFS代码

    #define maxnum 30 #include<bits_stdc++.h> int visited[maxnum]={0}; using namespace std; typede ...

  6. 获取Excel的单元格数据类型(靠谱)

    VBA中,单元格属性有NumberFormat可以获取单元格格式,比如: G/通式格式→常规 @→文本 yyyy/m/d→日期 问题: G/通式格式,无法知道值是整数还是浮点数, yyyy/m/d如果 ...

  7. iotop使用详解

    iotop是top和iostat程序的混合体,能够显示系统中所有运行进程并将进程根据I/O统计信息排序. 这个软件使用了Linux内核的一些新特性,所以需要2.6.20或者更新的内核. 一般默认情况下 ...

  8. 150行JavaScript代码实现增强现实

    增强现实技术(Augmented Reality,简称 AR),是一种实时地计算摄影机影像的位置及角度并加上相应图像.视频.3D模型的技术,这种技术的目标是在屏幕上把虚拟世界套在现实世界并进行互动.这 ...

  9. note05-计算机网络

    5.网络安全 被动攻击(UDP报文被截获 被 进行流量分析) 主动攻击 1.篡改(更改报文流 伪报文) 2.恶意程序(病毒.木马.蠕虫.炸弹) 3.拒绝服务Dos 密码体制 1.对称密钥密码体制(DE ...

  10. spring定时器quartz版本问题

    如果quartz的版本是1.8.5启动会报错,修改给2.0版本以上即可 <dependency> <groupId>org.quartz-scheduler</group ...