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个数,m个询问,每一个询问都是一个区间,让你先计算出这段区间所有数的gcd,然后问1~n所有连续区间中gcd的值等于询问区间gcd的区间个数。

思路:考虑到如果固定区间左端点L,那么右端点从L+1变化到n的过程中gcd最多变化log(区间内最大的数的大小)次(因为每次变化至少除以2),那么我们就可以枚举左端点,然后每次二分值连续的区间,然后都存到map里就行了。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<string>
#include<bitset>
#include<algorithm>
using namespace std;
#define lson th<<1
#define rson th<<1|1
typedef long long ll;
typedef long double ldb;
#define inf 99999999
#define pi acos(-1.0)
#define Key_value ch[ch[root][1]][0]
map<int,ll>mp;
map<int,ll>::iterator it; int q[100100][2]; int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
int gcd1[100100][30]; int a[100006];
void init_rmq(int n)
{
int i,j;
for(i=1;i<=n;i++){
gcd1[i][0]=a[i];
} for(j=1;j<=20;j++){
for(i=1;i<=n;i++){
if(i+(1<<j)-1<=n){
gcd1[i][j]=gcd(gcd1[i][j-1],gcd1[i+(1<<(j-1))][j-1]);
gcd1[i][j]=gcd(gcd1[i][j-1],gcd1[i+(1<<(j-1))][j-1]);
}
}
}
} int getgcd(int l,int r)
{
int k,i;
if(l>r)swap(l,r);
k=(log((r-l+1)*1.0)/log(2.0));
return gcd(gcd1[l][k],gcd1[r-(1<<k)+1][k]);
} int main()
{
int n,m,i,j,T,cas=0;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
}
mp.clear();
init_rmq(n);
int l,r,mid;
for(i=1;i<=n;i++){
//printf("----->%d\n",i);
int val=a[i];
int pos=i;
while(pos<=n){
val=getgcd(i,pos);
l=pos,r=n;
while(l<=r){
mid=(l+r)/2;
if(getgcd(i,mid)==val)l=mid+1;
else r=mid-1;
}
mp[val]+=(r-pos+1);
pos=l;
} }
scanf("%d",&m);
for(i=1;i<=m;i++){
scanf("%d%d",&q[i][0],&q[i][1]);
}
printf("Case #%d:\n",++cas);
for(i=1;i<=m;i++){
printf("%d %lld\n",getgcd(q[i][0],q[i][1]),mp[getgcd(q[i][0] ,q[i][1] ) ] );
}
}
return 0;
}

hdu5726 GCD(gcd +二分+rmq)的更多相关文章

  1. BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster( 后缀数组 + 二分 + RMQ + 树状数组 )

    全部串起来做SA, 在按字典序排序的后缀中, 包含每个询问串必定是1段连续的区间, 对每个询问串s二分+RMQ求出包含s的区间. 然后就是求区间的不同的数的个数(经典问题), sort queries ...

  2. HDU5726 GCD(二分 + ST表)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5726 Description Give you a sequence of N(N≤100, ...

  3. hdu 5726 GCD 暴力倍增rmq

    GCD/center> 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5726 Description Give you a sequence ...

  4. hdu 5726 GCD 倍增+ 二分

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

  5. HDU5726:GCD——题解

    题目:hdu的5726 (我原博客的东西,正好整理过来,属于st表裸题) (可以看出我当时有多么的菜--) 这道题写了一遍,然而蒟蒻的我的时间爆炸了-- 于是看了一下学长的代码(顺便在此处%一下学长) ...

  6. HDU 5726 GCD(ST&RMQ)

    题目链接 GCD 先ST倍增预处理,f[i][j]表示从i开始(包含第i个数)的连续2^j个数的最大公约数. 这样就可以在O(1)内询问得到a[l]到a[r]之间的所有数的最大公约数的值. 然后对于每 ...

  7. 2019CCPC-江西省赛C题 HDU6569 GCD预处理+二分

    Trap Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Subm ...

  8. HDU 5869 Different GCD Subarray Query rmq+离线+数状数组

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5869 Different GCD Subarray Query Time Limit: 6000/3 ...

  9. POJ 3419 Difference Is Beautiful (DP + 二分 + rmq)

    题意:给n个数(n<=200000),每个数的绝对值不超过(10^6),有m个查询(m<=200000),每次查询区间[a,b]中连续的没有相同数的的最大长度. 析:由于n太大,无法暴力, ...

随机推荐

  1. UnityToLaya小插件-找出空格并替换

    unity导出的文件中经常会出现带有空格的节点或者文件夹 而这些空格在本地开发测试过程中不会出现,当这些带有空格路径的文件需要放到网络上时,就出现问题了 所以这里写了一个简单的查找并清理空格的插件, ...

  2. 攻防世界 - Crypto(一)

    base64: 根据题目base64可知编码方式,下载附件发现是一个txt文件,把内容用工具解码就彳亍了,即可得到flag, flag: cyberpeace{Welcome_to_new_World ...

  3. ts类与修饰符

    最近在用egret做游戏,就接触到了ts,刚开始的时候觉得类挺难的,毕竟大多数的JavaScript工程师工作中不怎么需要用到这个,但是学起来就不愿意撒手了,真香! typescript其实是es6的 ...

  4. VMware下安装Ubantu 18.04

    一.VIM安装及配置 1.安装VIM sudo apt-get install vim 二.拼音输入法以及搜狗拼音输入法安装 1.安装Fcitx输入框架 sudo apt-get install fc ...

  5. java 利用异或^进行加密

    package com.zcj.eg001; import java.nio.charset.Charset; import org.junit.Test; public class Encrypti ...

  6. javascript通过递归改子节点数据-用于层级深度未知的树形结构

    最近在做这么个需求:树形结构,层级深度未知,一旦某个节点的状态是置灰的话,其所有子节点都要置灰. 方案一(数据库有值):如果数据库里置灰节点的所有子节点,值也都是"置灰",那后台取 ...

  7. ubuntu qt5.8 编译qtwebkit

    qtwebkit- 下载地址:http://download.qt.io/community_releases/5.8/5.8.0-final/ 问题一 出现如下错误 解决方法   sudo apt- ...

  8. C++ 无法打开 源 文件 "ntddk.h"

    原因是SDK版本太高了,或者版本不对应WDK,换一个SDK版本就好了.

  9. 电脑打不开gitHub的解决方法

    电脑打不开gitHub的解决方法 方法:修改本地的hosts文件 因为Github是国外网站,所以经常会遇到打不开的问题,并且有时能打开但是网速好慢 解决这个问题的方法是 :   C:\Windows ...

  10. 一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

    一套高可用.易伸缩.高并发的IM群聊.单聊架构方案设计实践 一套高可用.易伸缩.高并发的IM群聊.单聊架构方案设计实践-IM开发/专项技术区 - 即时通讯开发者社区! http://www.52im. ...