Different GCD Subarray Query

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
 

题意:

  长度n的序列, m个询问区间[L, R], 问区间内的所有子段的不同GCD值有多少种.

题解:

  固定右端点

  预处理出 每个点向左延伸 的 不同gcd值

  这样的 值不会超过log a 个

  然后问题就变成了 问你一段区间内不同 gcd 值有多少,值是很少的 (询问一个区间有多少颜色的题型)

  树状数组维护就可以了

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std; #pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair typedef long long LL;
const long long INF = 1e18;
const double Pi = acos(-1.0);
const int N = 1e6+, M = 1e2+, mod = 1e9+, inf = 2e9; int n,q,a[N],ans[N];
int gcd(int a, int b) { return b == ? a : gcd(b, a%b);}
vector<pii> G[N];
struct QQ{
int l,r,id;
bool operator < (const QQ &a) const {
return a.r > r;
}
}Q[N];
int C[N],vis[N];
void update(int x,int c) {
for(int i =x; i < N; i+=i&(-i)) C[i] += c;
}
int ask(int x) {
int s = ;
for(int i = x; i; i-= i & (-i))s += C[i];
return s;
}
int main() {
while(scanf("%d%d",&n,&q)!=EOF) {
for(int i = ; i <= n; ++i) scanf("%d",&a[i]);
for(int i = ; i <= n; ++i) G[i].clear();
for(int i = ; i <= n; ++i) {
int x = a[i];
int y = i;
for(int j = ; j < G[i-].size(); ++j) {
int res = gcd(x,G[i-][j].first);
if(x != res) {
G[i].push_back(MP(x,y));
x = res;
y = G[i-][j].second;
}
}
G[i].push_back(MP(x,y));
}
memset(C,,sizeof(C));
memset(vis,,sizeof(vis));
for(int i = ; i <= q; ++i) {scanf("%d%d",&Q[i].l,&Q[i].r),Q[i].id = i;}
sort(Q+,Q+q+);
for(int R = , i = ; i <= q; ++i) {
while(R < Q[i].r) {
R++;
for(int j = ; j < G[R].size(); ++j) {
int res = G[R][j].first;
int ids = G[R][j].second;
if(vis[res]) update(vis[res],-);
vis[res] = ids;
update(vis[res],);
}
}
ans[Q[i].id] = ask(R) - ask(Q[i].l-);
}
for(int i = ; i <= q; ++i) cout<<ans[i]<<endl;
}
return ;
}

HDU 5869 Different GCD Subarray Query 离线+树状数组的更多相关文章

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

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

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

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

  3. HDU 5869 Different GCD Subarray Query 树状数组 + 一些数学背景

    http://acm.hdu.edu.cn/showproblem.php?pid=5869 题意:给定一个数组,然后给出若干个询问,询问[L, R]中,有多少个子数组的gcd是不同的. 就是[L, ...

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

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

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

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

  6. HDU 5869 Different GCD Subarray Query

    离线操作,树状数组,$RMQ$. 这个题的本质和$HDU$ $3333$是一样的,$HDU$ $3333$要求计算区间内不同的数字有几个. 这题稍微变了一下,相当于原来扫描到$i$的之后是更新$a[i ...

  7. hdu 5869 Different GCD Subarray Query BIT+GCD 2016ICPC 大连网络赛

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

  8. HDU 5603 the soldier of love 离线+树状数组

    这是bestcorder 67 div1 的1003 当时不会做 看了赛后官方题解,然后翻译了一下就过了,而且速度很快,膜拜官方题解.. 附上官方题解: the soldier of love 我们注 ...

  9. 【刷题】HDU 5869 Different GCD Subarray Query

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

随机推荐

  1. 用extern定义全局变量

    1.extern的作用 extern有两个作用,第一个,当它与"C"一起连用时,如: extern "C" void fun(int a, int b); 则告 ...

  2. join

    一句话 join(param) 是把  array 连城一个字符串,中间用 param隔开

  3. struts2框架 初始别

    struts2 是webwork和struts合并而来. 1.下载struts2 说明: Full Distribution: 为完整版下载,建议下载它 Example Applications:st ...

  4. YY 神曲 李明霖 14部合集

    http://pan.baidu.com/s/1i5JIvXV

  5. a byte of python(摘04)

    a byte of python 第十章 输入/输出 如何使程序和用户进行交互?(用 raw_input 和 print语句来完成) 对于输出,你也可以使用多种多样的 str(字符串)类.使用 rju ...

  6. C#创建和调用WebService详细教程

    1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求, ...

  7. 【STL】重载运算符

    重载运算符 为什么要重载运算符: C++中预定义的运算符的操作对象只能是基本数据类型.但实际上,对于许多用户自定义类型(例如结构体),也需要类似的运算操作.这时就必须在C++中重新定义这些运算符,赋予 ...

  8. 【leetcode】 Interleaving String (hard)

    Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example,Given:s1 = ...

  9. 【leetcode】Next Permutation(middle)

    Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...

  10. IOS-Social.framework

    1.使用前 需要导入Social.framework 框架 2.实例代码(新浪微博为例) - (IBAction)shejiaoBtn {        // 判断服务器是否可用    if ([SL ...