GCD

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3432    Accepted Submission(s): 1227

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
 
 
题意:第一行T代表测试组数,第二行一个整数 N 代表长为 N 的序列,再一行是一个整数 Q ,代表有 Q 次询问,
然后 Q 行,每行两个整数 l,r 输出区间[l,r]的gcd 和有多少个区间 gcd 等于 gcd[l,r]
 
题解:想了很久,没想到好办法,后来发现RMQ这种问题,线段树还是不行的,如果离线的话,st表查询时间复杂度比线段树更小,为O(1)
st算法是用来求解给定区间RMQ的最值
学了st表后,查询有多少区间gcd==gcd[l,r]还是不知道怎么搞,题解是,用二分离线预处理...
 #include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std; #define LL long long
#define MAXN 100005 int n;
int num[MAXN];
int mn[MAXN];
int dp[MAXN][];
map<int,LL> res; int gcd(int a,int b)
{ return b==?a:gcd(b,a%b);} void Init()
{
mn[]=-;
for (int i=;i<=n;i++)
{
mn[i]=((i&(i-))==)?mn[i-]+:mn[i-];
dp[i][]=num[i];
}
for (int j=;j<=mn[n];j++)
for (int i=;i+(<<j)-<=n;i++)
{
dp[i][j]=gcd(dp[i][j-],dp[i+(<<(j-))][j-]);
}
} int st_calc(int l,int r)
{
int k = mn[r-l+];
return gcd(dp[l][k],dp[r-(<<k)+][k]);
} void erfen()
{
res.clear();
for (int i=;i<=n;i++) //以i为左起点的区间的所有公约数
{
int cur = i , gc = num[i]; //用二分求出
while (cur <= n)
{
int l=cur,r=n;
while(l<r)
{
int mid = (l+r+)>>;
if (st_calc(i,mid)==gc) l=mid;
else r = mid -;
}
if (res.count(gc)) res[gc]+=l-cur+;
else res[gc]=l-cur+;
cur = l + ;
if (cur<=n)
gc = gcd(gc,num[cur]);
}
}
} int main()
{
int t;
int cas=;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
for (int i=;i<=n;i++)
scanf("%d",&num[i]);
Init(); erfen(); int q;
scanf("%d",&q);
printf("Case #%d:\n",++cas);
while (q--)
{
int x,y;
scanf("%d%d",&x,&y);
int kk = st_calc(x,y);
printf("%d %lld\n",kk,res[kk]);
}
}
return ;
}
 
 

GCD(st表+二分)的更多相关文章

  1. 2016多校联合训练1 D题GCD (ST表+二分)

    暑假颓废了好久啊...重新开始写博客 题目大意:给定10w个数,10w个询问.每次询问一个区间[l,r],求出gcd(a[l],a[l+1],...,a[r])以及有多少个区间[l',r']满足gcd ...

  2. 「ZJOI2018」胖(ST表+二分)

    「ZJOI2018」胖(ST表+二分) 不开 \(O_2\) 又没卡过去是种怎么体验... 这可能是 \(ZJOI2018\) 最简单的一题了...我都能 \(A\)... 首先我们发现这个奇怪的图每 ...

  3. 【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分

    4310: 跳蚤 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 180  Solved: 83[Submit][Status][Discuss] De ...

  4. BZOJ4556 [Tjoi2016&Heoi2016]字符串 SA ST表 二分答案 主席树

    原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4556.html 题目传送门 - BZOJ4556 题意 给定一个长度为 $n$ 的字符串 $s$ . ...

  5. hdu5289 ST表+二分

    用裸的St表+暴力枚举查询时稳TLE的,可以枚举每个区间的起点+二分满足条件的区间右端,这样复杂度是O(nlogn) #include<iostream> #include<cstr ...

  6. luoguP5108 仰望半月的夜空 [官方?]题解 后缀数组 / 后缀树 / 后缀自动机 + 线段树 / st表 + 二分

    仰望半月的夜空 题解 可以的话,支持一下原作吧... 这道题数据很弱..... 因此各种乱搞估计都是能过的.... 算法一 暴力长度然后判断判断,复杂度\(O(n^3)\) 期望得分15分 算法二 通 ...

  7. 洛谷P4501/loj#2529 [ZJOI2018]胖(ST表+二分)

    题面 传送门(loj) 传送门(洛谷) 题解 我们对于每一个与宫殿相连的点,分别计算它会作为多少个点的最短路的起点 若该点为\(u\),对于某个点\(p\)来说,如果\(d=|p-u|\),且在\([ ...

  8. ZSTU 4241 圣杯战争(ST表+二分)

    题目链接  ZSTU 4241 问题转化为有很多区间,现在每次给定一个区间求这个区间和之前所有区间中的某一个的交集的最大长度. 强制在线. 首先我们把所有的区间预处理出来. 然后去重(那些被包含的小区 ...

  9. Codeforces 713D Animals and Puzzle(二维ST表+二分答案)

    题目链接 Animals and Puzzle 题意  给出一个1e3 * 1e3的01矩阵,给出t个询问,每个询问形如x1,y1,x2,y2 你需要回答在以$(x1, y1)$为左上角,$(x1, ...

随机推荐

  1. 在vs2012中配置使用iisexpress

    在vs2012中配置使用iisexpress   vs2012支持基于iisexpress的web站点调试,这样可以尽可能与生产环境具备一样的环境. 但是,如果在vs2012中直接配置iis目录,通常 ...

  2. Playonlinux

    apt-get install playonlinux -y apt-get install winbind -y apt-get install unzip -y 开始中搜索:playonlinux ...

  3. django 分页django-pure-pagination

    虽然django自带了一个paginator,但不是很方便,我们使用django-pure-pagination github地址https://github.com/jamespacileo/dja ...

  4. Jsp中如何在<c:forEach>标签内获取集合的长度

    利用jstl标签functions的prefix属性的length属性值 1.首先在jsp页面导入jstl function标签 <%@ taglib prefix="fn" ...

  5. Linux如何查找大文件

    https://www.cnblogs.com/kerrycode/p/4391859.html find . -type f -size +800M 如上命令所示,我们仅仅能看到超过800M大小的文 ...

  6. 【Java】String和Date、Timestamp之间的转换

    首先,定义一个Format的日期格式: SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 一.S ...

  7. javascript event loop

    原文: https://blog.csdn.net/sjn0503/article/details/76087631 简单来讲,整体的js代码这个macrotask先执行,同步代码执行完后有micro ...

  8. Java三大器之拦截器(Interceptor)的实现原理及代码示例

    1,拦截器的概念    java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了 ...

  9. const 使用方法具体解释

    const使用方法具体解释 面向对象是C++的重要特性.  可是c++在c的基础上新添加的几点优化也是非常耀眼的 就const直接能够代替c中的#define 下面几点非常重要,学不好后果也也非常严重 ...

  10. Git合并分支命令参数详解:git merge --ff

    今天研究了一下git merge命令常用参数,并分别用简单的例子实验了一下,整理如下: 输入命令git merge -h可以查看相关参数: --ff  快速合并,这个是默认的参数.如果合并过程出现冲突 ...