Different GCD Subarray Query

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 828    Accepted Submission(s): 300

Problem Description
This is a simple problem. The teacher gives Bob a list of problems about GCD (Greatest Common Divisor). After studying some of them, Bob thinks that GCD is so interesting. One day, he comes up with a new problem about GCD. Easy as it looks, Bob cannot figure it out himself. Now he turns to you for help, and here is the problem:
  
  Given an array a of N positive integers a1,a2,⋯aN−1,aN; a subarray of a is defined as a continuous interval between a1 and aN. In other words, ai,ai+1,⋯,aj−1,aj is a subarray of a, for 1≤i≤j≤N. For a query in the form (L,R), tell the number of different GCDs contributed by all subarrays of the interval [L,R].
  
 
Input
There are several tests, process till the end of input.
  
  For each test, the first line consists of two integers N and Q, denoting the length of the array and the number of queries, respectively. N positive integers are listed in the second line, followed by Q lines each containing two integers L,R for a query.

You can assume that 
  
    1≤N,Q≤100000 
    
   1≤ai≤1000000

 
Output
For each query, output the answer in one line.
 
Sample Input
5 3
1 3 4 6 9
3 5
2 5
1 5
 
Sample Output
6
6
6
 
Source

题意:有n个数字依次存放在一个数组中(n<=1e5),每个数字<=1e6,数组中每个子序列可以产生一个整个子序列的最大公约数,有q个询问(q<=1e5),每次询问包括两个数字,l,r询问下标从l,到r的区间内一共有多少个不同的GCD;

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#define MM(a,b) memset(a,b,sizeof(a));
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
#define CT continue
#define SC scanf
const int N=1e5+10;
int n,qur,a[N],tree[N],ans[N],pos[10*N]; struct node{
int l,id;
}; int gcd(int a,int b)
{
if(b==0) return a;
else return gcd(b,a%b);
} int lowbit(int i)
{
return i&(-i);
} int add(int pos,int val)
{
while(pos<=n){
tree[pos]+=val;
pos+=lowbit(pos);
}
} int query(int r)
{
int s=0;
while(r>=1){
s+=tree[r];
r-=lowbit(r);
}
return s;
} vector<node> q[N],lgcd[N]; void solve()
{
for(int i=1;i<=n;i++){
if(pos[a[i]]!=-1) add(pos[a[i]],-1);
pos[a[i]]=i;
add(i,1);
int val=a[i];
for(int j=i-1;j>=1;j--){
int k=gcd(val,a[j]);
if(pos[k]<j){
if(pos[k]!=-1) add(pos[k],-1);
pos[k]=j;
add(j,1);
}
if(k==1) break;
val=k;
}
for(int j=0;j<q[i].size();j++){
int l=q[i][j].l,id=q[i][j].id;
ans[id]=query(i)-query(l-1);
}
}
} int main()
{
while(~SC("%d%d",&n,&qur)){
MM(tree,0);
MM(pos,-1);
for(int i=1;i<=n;i++) {
SC("%d",&a[i]);
q[i].clear();
}
for(int i=1;i<=qur;i++) {
int l,r;
SC("%d%d",&l,&r);
q[r].push_back((node){l,i});
}
solve();
for(int i=1;i<=qur;i++) printf("%d\n",ans[i]);
}
return 0;
}

  分析:

错因分析:比赛的时候想到了每个数字的gcd并不会很多,,但是想到的解决方法是,先统计出从1到i(1<=i<=n)的各个位置所拥有的gcd种类数,,然后对于一个区间[l,r],用种类数r-种类数l-1,,,,但是这样有个很显然的错误就是[l,l-1]内出现的gcd有可能在[l,r]内再次出现,所以这样肯定就错了

纠正与解答:对于这样的问题,

1.我们可以从1-n依次固定右端点,然后从i向前扫,得到一个gcd,然后用BIT维护其gcd最靠右位置,在BIT中+1(可以想象,固定右端点后,越靠右,则不管怎样的区间,都尽可能包含)

2.最多在loga时间内gcd衰减至1.复杂度nlogn*logn;

hdu 5869 Different GCD Subarray Query BIT+GCD 2016ICPC 大连网络赛的更多相关文章

  1. HDU 4004 The Frog's Games(2011年大连网络赛 D 二分+贪心)

    其实这个题呢,大白书上面有经典解法  题意是青蛙要跳过长为L的河,河上有n块石头,青蛙最多只能跳m次且只能跳到石头或者对面.问你青蛙可以跳的最远距离的最小值是多大 典型的最大值最小化问题,解法就是贪心 ...

  2. HDU 5869 Different GCD Subarray Query rmq+离线+数状数组

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5869 Different GCD Subarray Query Time Limit: 6000/3 ...

  3. HDU 5869 Different GCD Subarray Query 离线+树状数组

    Different GCD Subarray Query Problem Description   This is a simple problem. The teacher gives Bob a ...

  4. HDU 5869.Different GCD Subarray Query-区间gcd+树状数组 (神奇的标记右移操作) (2016年ICPC大连网络赛)

    树状数组... Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/6 ...

  5. 2016大连网络赛 Different GCD Subarray Query

    Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K ( ...

  6. 树状数组 gcd 查询 Different GCD Subarray Query

    Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K ( ...

  7. HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gc ...

  8. HDU 5869 Different GCD Subarray Query 树状数组+离线

    Problem Description This is a simple problem. The teacher gives Bob a list of problems about GCD (Gr ...

  9. HDU 5869 Different GCD Subarray Query(2016大连网络赛 B 树状数组+技巧)

    还是想不到,真的觉得难,思路太巧妙 题意:给你一串数和一些区间,对于每个区间求出区间内每段连续值的不同gcd个数(该区间任一点可做起点,此点及之后的点都可做终点) 首先我们可以知道每次添加一个值时gc ...

随机推荐

  1. poi 3061 尺取例题1

    题目传送门/res tp poj 白书题 尺取法例题 #include<iostream> #include<algorithm> using namespace std; c ...

  2. 剑指offer12:求解double类型的浮点数base和int类型的整数exponent的次方。 保证base和exponent不同时为0

    1. 题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方.保证base和exponent不同时为0. 2. 思路和方法 分析: 由于 ...

  3. P1040 加分二叉树(区间DP)

    (点击此处查看原题) 解题思路 题目已经给出了树的中序遍历,因此我的想法是利用中序遍历的特点:若某子树的根结点为k,那么k之前的结点组成这一子树的左子树,k之后的结点组成这一子树的右子树,可以通过不断 ...

  4. Istio技术与实践02:源码解析之Istio on Kubernetes 统一服务发现

    前言 文章Istio技术与实践01: 源码解析之Pilot多云平台服务发现机制结合Pilot的代码实现介绍了Istio的抽象服务模型和基于该模型的数据结构定义,了解到Istio上只是定义的服务发现的接 ...

  5. Antd中,Form和Select联合使用,导致placeholder不生效分析

    在使用antd的form组件时候,需要对Select组件进行语体示,placeholder,但是写的值并不生效 效果如上,但是现实的时候不生效,经检查发现,组件需要传递的是undefined,如果传入 ...

  6. CodeFirst实体类中,为什么都把ICollection<x>定义成virtual?

    主要是用于延迟加载,提高性能用的 只有定义成virtual后才可以延迟加载. 延迟加载,默认情况下,延迟加载被支持,如果你希望禁用它,必须显式声明,最好的位置是在 DbContext 的构造器中. p ...

  7. WP8的新功能-通过一个程序来启动另一个程序

    Wp8对原来的WP7做了大量的优化...其中一个就包括Protocol Association,也就是通过uri来打开另外一个程序,这也就是说,我们可以做一个程序来启动另外一个程序了,如微信,QQ之类 ...

  8. excel隔行取数据

    .6…行数据取出来 好用的公式推荐出来 1.3.5…和2.4.6…行数据取出来 在空白单元格输入=OFFSET(A2,ROW(A2)-2,0) 或=OFFSET(A1,ROW(A1),0) #1,3, ...

  9. SpringAOP的实现方式

    1.使用SpringAPI实现AOP <aop:config> <!-- 切入点:需要操作的目标类中的目标方法 execution中只需要修改全类名 --> <aop:p ...

  10. VMware无法连接MKS:套接字连接尝试次数太多解决

    粘贴自:https://jingyan.baidu.com/article/425e69e61eb578be15fc16ae.html VMware在开启虚拟机的时候,突然弹出[无法连接MKS:套接字 ...