HDU5726 GCD(二分 + ST表)
题目
Source
http://acm.hdu.edu.cn/showproblem.php?pid=5726
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个数的序列,多次询问有多少个区间GCD值等于某个区间的gcd值。
任何一个区间不同的GCD个数是log级别的,因为随着右端点向右延伸GCD是单调不增的,而每次递减GCD至少除以2。
考虑固定左端点,最多就nlogn种GCD,可以直接把所有区间GCD值预处理出来,用map存储各种GCD值的个数,查询时直接输出。
具体是这样处理的:枚举左端点,进行若干次二分查找,看当前GCD值最多能延伸到哪儿,进而统计当前GCD值的数量。
而求区间GCD,用ST表,预处理一下,就能在O(1)时间复杂度求出任意区间的gcd了。
代码
#include<cstdio>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std; int gcd(int a,int b){
while(b){
int t=b;
b=a%b;
a=t;
}
return a;
} int n,st[17][111111];
void init(){
for(int i=1; i<17; ++i){
for(int j=1; j<=n; ++j){
if(j+(1<<i)-1>n) continue;
st[i][j]=gcd(st[i-1][j],st[i-1][j+(1<<i-1)]);
}
}
}
int logs[111111];
int query(int a,int b){
int k=logs[b-a+1];
return gcd(st[k][a],st[k][b-(1<<k)+1]);
} int main(){
for(int i=1; i<=100000; ++i){
logs[i]=log2(i)+1e-6;
}
int t;
scanf("%d",&t);
for(int cse=1; cse<=t; ++cse){
scanf("%d",&n);
for(int i=1; i<=n; ++i){
scanf("%d",&st[0][i]);
} init(); map<int,long long> rec;
for(int i=1; i<=n; ++i){
int g=st[0][i],j=i;
while(j<=n){
int l=j,r=n;
while(l<r){
int mid=l+r+1>>1;
if(query(i,mid)==g) l=mid;
else r=mid-1;
}
rec[g]+=(l-j+1);
j=l+1;
g=query(i,j); }
} printf("Case #%d:\n",cse);
int q,a,b;
scanf("%d",&q);
while(q--){
scanf("%d%d",&a,&b);
int g=query(a,b);
printf("%d %lld\n",g,rec[g]);
}
}
return 0;
}
HDU5726 GCD(二分 + ST表)的更多相关文章
- BZOJ4556:[TJOI\HEOI2016]字符串(后缀数组,主席树,二分,ST表)
Description 佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了一个长为n的字符串s,和m个问题.佳媛姐姐必须正确回答这m个问题,才能打开箱 ...
- BZOJ3166 [Heoi2013]Alo 【可持久化trie树 + 二分 + ST表】
题目 Welcome to ALO ( Arithmetic and Logistic Online).这是一个VR MMORPG , 如名字所见,到处充满了数学的谜题. 现在你拥有n颗宝石,每颗宝石 ...
- [BZOJ4310] 跳蚤 - 后缀数组,二分,ST表
[BZOJ4310] 跳蚤 Description 首先,他会把串分成不超过 \(k\) 个子串,然后对于每个子串 \(S\) ,他会从 \(S\) 的所有子串中选择字典序最大的那一个,并在选出来的 ...
- Codeforces 359D Pair of Numbers | 二分+ST表+gcd
题面: 给一个序列,求最长的合法区间,合法被定义为这个序列的gcd=区间最小值 输出最长合法区间个数,r-l长度 接下来输出每个合法区间的左端点 题解: 由于区间gcd满足单调性,所以我们可以二分区间 ...
- ZJOI2018 胖 二分 ST表
原文链接https://www.cnblogs.com/zhouzhendong/p/ZJOI2018Day2T2.html 题目传送门 - BZOJ5308 题目传送门 - LOJ2529 题目传送 ...
- BZOJ 5308 [ZJOI2018] Day2T2 胖 | 二分 ST表
题目链接 LOJ 2529 BZOJ 5308 题解 这么简单的题 为什么考场上我完全想不清楚 = = 对于k个关键点中的每一个关键点\(a\),二分它能一度成为哪些点的最短路起点(显然这些点在一段包 ...
- BZOJ3473:字符串(后缀数组,主席树,二分,ST表)
Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一 ...
- BZOJ 3230 相似子串 | 后缀数组 二分 ST表
BZOJ 3230 相似子串 题面 题解 首先我们要知道询问的两个子串的位置. 先正常跑一遍后缀数组并求出height数组. 对于每一个后缀suffix(i),考虑以i开头的子串有多少是之前没有出现过 ...
- BZOJ3230 相似子串[后缀数组+二分+st表]
BZOJ3230 相似子串 给一个串,查询排名i和j的子串longest common suffix和longest common prefix 思路其实还是蛮好想的,就是码起来有点恶心.可以发现后缀 ...
随机推荐
- 25个增强iOS应用程序性能的提示和技巧(高级篇)(1)
25个增强iOS应用程序性能的提示和技巧(高级篇)(1) 2013-04-16 14:56 破船之家 beyondvincent 字号:T | T 在开发iOS应用程序时,让程序具有良好的性能是非常关 ...
- iOS开发人员不容错过的10大工具
内容简介 1.iOS简介 2.iOS开发十大实用工具之开发环境 3.iOS开发十大实用工具之图标设计 4.iOS开发十大实用工具之原型设计 5.iOS开发十大实用工具之演示工具 6.iOS开发十大实用 ...
- git push 使用总结
git push命令用于将本地分支的更新,推送到远程主机.它的格式与git pull命令相仿. $ git push <远程主机名> <本地分支名>:<远程分支名> ...
- 攻城狮在路上(叁)Linux(二十五)--- linux内存交换空间(swap)的构建
swap的功能是应付物理内存不足的状况,用硬盘来暂时放置内存中的信息. 对于一般主机,物理内存都差不多够用,所以也就不会用到swap,但是对于服务器而言,当遇到大量网络请求时或许就会用到. 当swap ...
- 攻城狮在路上(叁)Linux(二十)--- Linux磁盘格式化
磁盘完成分区之后,进行格式化,生成文件系统. 命令格式: mkfs [-t 文件系统格式] 设备文件名 <== 使用 mkfs [Tab][Tab] 可以查看linux支持的文件系统格式 示例 ...
- Oracle 数据泵文件
数据泵文件 expdp介绍 EXPDP命令行选项1. ATTACH该选项用于在客户会话与已存在导出作用之间建立关联.语法如下ATTACH=[schema_name.]job_nameSchema_na ...
- PMP 第八章 项目质量管理
1规划质量 2实施质量保证 3实施质量控制 质量成本 1.等级和质量的区别?现代质量管理的重要性,关注图8-2 质量是一些列内在特性满足要求的程度,而等级是对用途相同但技术特性不同的产品或服务的 ...
- 思想&观点&人生
思想: 思想的直接表现往往是对事物的观点,观点越多并且越接近本质,表示思想越丰富和深刻 观点不是事实 观点是基于事实之上的一种系统性的判断和理解框架,事实是观点的基础 观点不一定正确 观点组成: 事实 ...
- 单例模式/singleton模式/创建型模式
Java实现要点: 私有构造方法 线程安全(并发的考虑) 延迟加载(效率的考虑,对于较大的类在使用时在加载) 公有方法访问单一实例 常见单例模式代码及问题 //无延迟加载,常驻内存(即使不使用) cl ...
- Atom 和 markdown 基本使用
Atom 和 markdown 基本使用 Atom 常用的快捷键 Cmd + Shift + P 打开命令窗口,可以运行各种菜单功能. Cmd + T 快速的多文件切换 Ctrl + G 文件内跳转到 ...