题目链接

给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 倍增+ 二分的更多相关文章

  1. HDU 5726 GCD (RMQ + 二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 给你n个数,q个询问,每个询问问你有多少对l r的gcd(a[l] , ... , a[r]) ...

  2. HDU 5726 GCD 区间GCD=k的个数

    GCD Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submis ...

  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(RMQ+二分)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5726 题意:给出一串数字,现在有多次询问,每次询问输出(l,r)范围内所有数的gcd值,并且输出有多 ...

  5. HDU 5726 GCD (2016多校、二分、ST表处理区间GCD、数学)

    题目链接 题意 : 给出一个有 N 个数字的整数数列.给出 Q 个问询.每次问询给出一个区间.用 ( L.R ) 表示.要你统计这个整数数列所有的子区间中有多少个和 GCD( L ~ R ) 相等.输 ...

  6. HDU 5726 GCD(DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5726 [题目大意] 给出数列An,对于询问的区间[L,R],求出区间内数的GCD值,并且求出GCD ...

  7. HDU 5726 GCD(ST&RMQ)

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

  8. HDU 5726 GCD

    传送门 GCD Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem ...

  9. HDU 5726 GCD (2016 Multi-University Training Contest 1)

      Time Limit: 5000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Description Give y ...

随机推荐

  1. Gitlab管理下本地Git配置

    公司项目组用的是Gitlab,组内成员分配有有固定的git个人账户,不同成员有不同的模块编辑权限,使用前需要配置好本地的Git.对一直使用svn的小菜菜来说,这个还是需要一点步骤配置下才可以使用的.配 ...

  2. OC-类

    1.关于头文件 #include <stdio.h>     #import <Foundation/Foundation.h> 区别:#import指令导入更快更有效率.#i ...

  3. KZ--NSString、NSMutableString

            //NSString初始化的几种方法(3种方法)         //1.         NSString *str2 = [[NSString alloc] init];      ...

  4. C++<algorithm>中sort的比较函数写法(转)

    转自:http://www.wl566.com/biancheng/98907.html C++<algorithm>中sort的比较函数写法,有需要的朋友可以参考下. 定义排序函数: 方 ...

  5. c++的getline()和get()函数

    这两个函数都是面向行的输入: getline()函数读取整行,它使用通过回车符来确定输入结尾.要调用这种方法,可以使用cin.getline().该函数有两个参数, 第一个参数用来存储输入行的数组的名 ...

  6. 35个jQuery小技巧!

    1. 禁止右键点击$(document).ready(function(){    $(document).bind("contextmenu",function(e){     ...

  7. eclipse IDE 扩展pydev

    1. 安装PyDev. 运行Eclipse,打开菜单Help->Install New Software.在work with里输入网址:http://pydev.org/updates ,然后 ...

  8. openjpa框架入门_项目框架搭建(二)

    Openjpa2.2+Mysql+Maven+Servlet+JSP 首先说明几点,让大家更清楚整体结构: 官方source code 下载:http://openjpa.apache.org/dow ...

  9. ajax跨域请求的方案

    $.get("@Hosts.Default.Www/api/XXXXX/Getxxx/"+@Model.UserId, function(data) { $("#tota ...

  10. 谷歌page speed 安装使用及页面问题详解

    原文地址:http://wenku.baidu.com/view/b0a61f3ebcd126fff7050b40.html 谷歌page speed 安装使用及页面问题详解 谷歌page speed ...