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 ...
随机推荐
- IBM WebSphere MQ的C#工具类以及源码(net)
简单的介绍一下MQ常用的对象 Queue Manager 队列管理器 主要负责管理队列.通道等,类似与Oracle中的Oracle实例的概念,在一台服务器中可以定义多个Queue Manager. Q ...
- Android之Socket通信(一)
一.服务器端,运行在PC机上 import java.io.*; import java.net.*; public class SimpleServer{ public static voi ...
- 看懂此文,不再困惑于 JS 中的事件设计
看懂此文,不再困惑于 JS 中的事件设计 今天刚在关注的微信公众号看到的文章,关于JS事件的,写的很详细也很容易理解,相关的知识点都有总结到,看完就有种很舒畅的感觉,该串起来的知识点都串起来了.反正一 ...
- python函数与方法装饰器
之前用python简单写了一下斐波那契数列的递归实现(如下),发现运行速度很慢. def fib_direct(n): assert n > 0, 'invalid n' if n < 3 ...
- putty修改编码
在窗口标题上点击右键,选择 Change Settings... 在打开的配置窗口左边选择 Appearance,在右边点 Font settings 里面的 Change 按钮,选择好中文字体,比如 ...
- Spring随笔 - 事务隔离级别
Spring提供5中事务隔离级别: ISOLATION_DEFAULT:使用数据库后端的默认隔离级别. ISOLATION_READ_UNCOMMITTED:允许读取尚未提交的数据变更.可能会导致脏读 ...
- java如何防止反编译
综述(写在前面的废话) Java从诞生以来,其基因就是开放精神,也正因此,其可以得到广泛爱好者的支持和奉献,最终很快发展壮大,以至于有今天之风光!但随着java的应用领域越来越广,特别是一些功能要发布 ...
- 1.offsetParent,offsetLeft,offsetTop
offsetParent <!doctype html> <html> <head> <meta charset="utf-8"> ...
- “如何稀释scroll事件”引出的问题
背景:我在segmentfault提了个问题如何稀释onscroll事件,问题如下: 面试时问到这个问题,是这样的: 面试官问一个关于滚动到某个位置的时候出现一个顶部的导航栏,答完之后,她接着问 ...
- Java 集合嵌套List of List
在LeetCode上遇到这样返回值 public class Solution { public List<List<Integer>> levelOrder(TreeNode ...