题目链接

给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. ASP.NET中的路径(path) 详解

    一 ASP.NET常用路径(path)获取方法与格式对照表 假设我们的网址为http://localhost:1897/ News/Press/Content.aspx?id=1019 跟 Brows ...

  2. c# 读取IntPtr 中的数据

    c++的写法是这样的:LRESULT CPictureQueryDlg::OnQueryPicNty(WPARAM wp, LPARAM lp){EnableWindow(TRUE); BYTE *p ...

  3. Python Challenge

    0. 2的38次方 print 2**38 ##apply the result to the url 1. 看图是要right shift两位, 切片即可. import string intab ...

  4. phpstorm 设置多项目并存

    phpstorm 或 webstorm 设置多个项目可以并存: File -> settings -> Directories -> Add Content Root 中添加你当前的 ...

  5. AOP-----动态代理(转)

    动态代理是实现AOP的绝好底层技术 JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler.其中 InvocationHandler是 ...

  6. Android之 compileSdkVersion, minSdkVersion, and targetSdkVersion

    在一年之中,也有可能只是几个月后,你会发布你的Android应用程序.但是这中间有可能会发布新的版本的Android系统,比如:6.0+. 你肯定希望你的应用可以向前兼容,当用户升级到新的Androi ...

  7. Service(Local Service)简介

    一.Service的作用 主要用于在后台处理一些耗时的逻辑操作,或者去执行某些长期运行的操作. 二.Service的创建 1.主要方法 IBinder onBind(Intent intent):必须 ...

  8. C++ Primer第18章Vector的再实现及bug修正

    C++Primer第18.1.2节在介绍allocator类的时候,给了一个仿照标准库中vector的例子.感觉示例代码非常好,但是本人发现了一个bug,与大家共享. 按照作者的示例程序,编译程序时总 ...

  9. 解析Tensorflow官方English-Franch翻译器demo

    今天我们来解析下Tensorflow的Seq2Seq的demo.继上篇博客的PTM模型之后,Tensorflow官方也开放了名为translate的demo,这个demo对比之前的PTM要大了很多(首 ...

  10. EditPlus3.3 集成 SVN

    今天在玩EditPlus的时候,由于自己想上传文件至SVN,本机已经安装了TSVN,听说近期EditPlus支持了SVN操作,于是自己便带着好奇的心试试了.     已有的环境: EditPlus 3 ...