hdu 5726 GCD 倍增+ 二分
给n个数, 定义一个运算f[l,r] = gcd(al, al+1,....ar)。 然后给你m个询问, 每次询问给出l, r。 求出f[l, r]的值以及有多少对l', r' 使得f[l, r] = f[l', r']。
第一个很简单, 用倍增的思想就可以了。
然后是第二个, 我们枚举每一个左端点i, 显然f[i, j]是只降不增的。 那么我们可以二分找到所有使得f[i, j]下降的值j。 因为gcd每次至少变为原来的二分之一, 而ai最大为1e9. 所以最多只有log2(1e9)个这样的点。 我们都找出来然后放到map里就可以了。 具体看代码
#include <bits/stdc++.h> using namespace std;
#define ll long longint n;
const int maxn = 1e5+;
int a[maxn], f[maxn][], mm[maxn];
map <int, ll> mp;
int gcd(int a, int b)
{
return b?gcd(b, a%b):a;
}
void initrmq()
{
mm[] = -;
for(int i = ; i <= n; i++) {
mm[i] = ((i&(i-))==)?mm[i-]+:mm[i-];
}
for(int j = ; j < ; j++) {
for(int i = ; i + (<<j)- <= n; i++) {
f[i][j] = gcd(f[i][j-], f[i+(<<(j-))][j-]);
}
}
}
int query(int l, int r)
{
int k = mm[r-l+];
return gcd(f[l][k], f[r-(<<k)+][k]);
}
void pre()
{
for(int i = ; i <= n; i++) {
int g = f[i][];
int L = i, tmp;
while(L <= n) {
int l = L, r = n;
while(l <= r) {
int mid = l+r>>;
if(query(i, mid) == g) {
tmp = mid;
l = mid+;
} else {
r = mid-;
}
}
mp[g] += (tmp-L+);
L = tmp+;
g = gcd(g, f[L][]);
}
}
}
int main()
{
int t, m, l, r;
cin>>t;
for(int casee = ; casee <= t; casee++) {
cin>>n;
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
f[i][] = a[i];
}
mp.clear();
initrmq();
pre();
cin>>m;
printf("Case #%d:\n", casee);
for(int i = ; i < m; i++) {
scanf("%d%d", &l, &r);
int ans = query(l, r);
printf("%d %lld\n", ans, mp[ans]);
}
}
}
hdu 5726 GCD 倍增+ 二分的更多相关文章
- HDU 5726 GCD (RMQ + 二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 给你n个数,q个询问,每个询问问你有多少对l r的gcd(a[l] , ... , a[r]) ...
- HDU 5726 GCD 区间GCD=k的个数
GCD Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...
- hdu 5726 GCD 暴力倍增rmq
GCD/center> 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5726 Description Give you a sequence ...
- HDU 5726 GCD(RMQ+二分)
http://acm.split.hdu.edu.cn/showproblem.php?pid=5726 题意:给出一串数字,现在有多次询问,每次询问输出(l,r)范围内所有数的gcd值,并且输出有多 ...
- HDU 5726 GCD (2016多校、二分、ST表处理区间GCD、数学)
题目链接 题意 : 给出一个有 N 个数字的整数数列.给出 Q 个问询.每次问询给出一个区间.用 ( L.R ) 表示.要你统计这个整数数列所有的子区间中有多少个和 GCD( L ~ R ) 相等.输 ...
- HDU 5726 GCD(DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5726 [题目大意] 给出数列An,对于询问的区间[L,R],求出区间内数的GCD值,并且求出GCD ...
- HDU 5726 GCD(ST&RMQ)
题目链接 GCD 先ST倍增预处理,f[i][j]表示从i开始(包含第i个数)的连续2^j个数的最大公约数. 这样就可以在O(1)内询问得到a[l]到a[r]之间的所有数的最大公约数的值. 然后对于每 ...
- HDU 5726 GCD
传送门 GCD Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem ...
- HDU 5726 GCD (2016 Multi-University Training Contest 1)
Time Limit: 5000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Description Give y ...
随机推荐
- BS常用方法备忘
在B/S项目开发过程中总结的一些常用方法,如:常量.验证方法.服务器控件方法.html控件方法等. ///******************* 说明 ************************ ...
- 初学.NET小技巧(不断更新)
1.快速打出Console.WriteLine : 输入cw,然后按两下tab键. 2.创建一个函数快捷键:bool b = IsPrimeNumber(); 把光标放到函数名上,Shift+Al ...
- 使用UTL_SMTP发送中文电子邮件
就是在原有TOM源码的基础上修改utl_smtp.write_data中,将输出内容进行一下数据转换,这样可以保证中文输出不会出现乱码 ----------------------------- cr ...
- AsyncTask 不能与Thread.sleep()同时使用解决方案
public class MainActivity extends Activity { private ImageView iv_ads; String urrstrString = "h ...
- JavaScript的原型
//回顾构造函数 function Box(name, age) { this.name = name; //实例属性 this.age = age; this.run = function() { ...
- json、map互转
首先,json转map 方法一: Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); 或 Gs ...
- LED发光二极管
半导体发光器件包括半导体发光二极管(简称LED).数码管.符号管.米字管及点阵式显示屏(简称矩阵管)等.事实上,数码管.符号管.米字管及矩阵管中的每个发光单元都是一个发光二极管. 一. 半导体发光二极 ...
- 960 grid 分析
960 网格系统的构造如下:页面总宽度 960px12 栏布局, 每栏 60px每栏两边保留 10px 的外边距, 相当于 20px 的槽内容区域总宽度是 940px 960 布局无疑是非常好的网格系 ...
- 中国市场 Android App 兼容性报告
由于手机操作系统的不同,以及操作系统版本之间的差异,使得真机测试这个过程尤其复杂,涉及终端.人员.工具.时间.管理等方面的问题,Android系统的设备因操作系统多样性和终端类型的庞杂,问题尤为复 ...
- VS2005设置Release模式可调试
from:http://www.cppblog.com/fwxjj/archive/2009/09/25/97219.html