【HDOJ 5726】GCD(RMQ+二分)
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
Sample Output
题意:
有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+二分)的更多相关文章
- HDU 5726 GCD (RMQ + 二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 给你n个数,q个询问,每个询问问你有多少对l r的gcd(a[l] , ... , a[r]) ...
- 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)个区间查询[ ...
- GCD (RMQ + 二分)
RMQ存的是区间GCD,然后遍历 i: 1->n, 然后不断地对[i, R]区间进行二分求以i为起点的相同gcd的区间范围,慢慢缩减区间. #include<bits/stdc++.h&g ...
- hdu 5726 GCD 倍增+ 二分
题目链接 给n个数, 定义一个运算f[l,r] = gcd(al, al+1,....ar). 然后给你m个询问, 每次询问给出l, r. 求出f[l, r]的值以及有多少对l', r' 使得f[l, ...
- HDU 5726 GCD (2016多校、二分、ST表处理区间GCD、数学)
题目链接 题意 : 给出一个有 N 个数字的整数数列.给出 Q 个问询.每次问询给出一个区间.用 ( L.R ) 表示.要你统计这个整数数列所有的子区间中有多少个和 GCD( L ~ R ) 相等.输 ...
- HDU 5726 GCD 区间GCD=k的个数
GCD Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...
- *HDU3486 RMQ+二分
Interviewe Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- hdu 5289 Assignment(2015多校第一场第2题)RMQ+二分(或者multiset模拟过程)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 题意:给你n个数和k,求有多少的区间使得区间内部任意两个数的差值小于k,输出符合要求的区间个数 ...
- hdu 3486 Interviewe (RMQ+二分)
Interviewe Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分
原文地址:http://www.cnblogs.com/GXZlegend/p/6825389.html 题目描述 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一 ...
随机推荐
- 13.git别名
虽然别名不是很重要,但是你大概应该知道如何使用它们. Git 并不会在你输入部分命令时自动推断出你想要的命令. 如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每 ...
- 使用C++11实现完美资源管理
1.资源管理包括内存管理.文件句柄等等需要进行打开(申请).关闭(释放)操作的过程 2.VS2010使用的C++规范,严格说来不是C++11,而是C++0x,但是一脉相承的 一:管理数组 相较于aut ...
- golang构造函数
http://blog.jobbole.com/107442/?utm_source=blog.jobbole.com&utm_medium=relatedPosts https://gocn ...
- SQL Server ->> Database Promgramming Object Security Control(数据库编程对象安全控制)
对于SQL Server内编程对象的安全控制是今天我在思考的问题.在MSDN上找到了几篇有用的文章. 首先微软推荐了三种做法: 1)第一种做法是在SQL Server中对一个应用程序对应创建应用程序角 ...
- 快速替换dll命名空间 z
Step1:使用ildasm将代码反编译成il中间语言. 名字存贮为你想要的名字. Step2:用记事本打开il文件全局替换命名空间. Step3:使用ilasm将il文件编译成dll 按下回车即可生 ...
- Asp ose.Tota l for .NET 2015
How to license Aspose.Total for .NET products Add "License.cs" [C#] OR "License.vb&qu ...
- Python初学者第四天 二进制运转换
4day 1.二进制运算 a.十进制转换二进制 342 转换成二进制 342 101010110 Python提供了一种简单的计算二进制的方法:bin() b.文字转换成二进制 ASCII码表 GB ...
- Android Studio 独立引入(非友盟)微博分享和回调时问题
最近同事在做一个小项目时,由于产品的要求,Wap页面的分享规定不能使用友盟的社会化组件.他则不得不手动一个一个渠道的引入分享,好在渠道不多就三个,但是第一微博分享引入的时候问题就出现了. 问题一:li ...
- PHP 获取数组随意下标key的上一个prev和下一个next下标值
PHP 获取数组随意下标key的上一个prev和下一个next下标值 <? php $xoops[1] = '小'; $xoops[2] = '孩'; $xoops[3] = '子'; $xoo ...
- c#根据当前时间获取本周,本月,本年度等时间段和DateTime日期格式化
DateTime dt = DateTime.Now; //当前时间 DateTime startWeek = dt.AddDays( - Convert.ToInt32(dt.DayOfWeek.T ...