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. Linux下常用的硬件信息查看命令

    1.查看CPU型号,这里为了方便查看结合管道符用grep进行了匹配,当然只需要前面的命令也可以,命令如下: cat /proc/cpuinfo | grep "model name" ...

  2. AJAX学习

    AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术.AJAX代码运行在客户端,其和服务器进行交互 ...

  3. CentOS搭建svn服务器支持https访问

    在CentOS6.3 64位机器上配置SVN服务器,并设置只允许HTTPS连接,可以配置多个repos源,每个源都拥有自己的组和成员,用于权限控制. 安装相关软件 Apache yum install ...

  4. Python: 安装BeautifulSoup4

    python3.4.3 安装BeautifulSoup4: 使用pip install 安装: 在命令行cmd之后输入,pip install BeautifulSoup4 BeautifulSoup ...

  5. Java Web开发框架Spring+Hibernate整合效果介绍(附源码)

    最近花了一些时间整合了一个SpringMVC+springAOP+spring security+Hibernate的一套框架,之前只专注于.NET的软件架构设计,并没有接触过Java EE,好在有经 ...

  6. shiro的简单使用

    <?xml version="1.0" encoding="utf-8"?> <web-app xmlns:xsi="http:// ...

  7. 【EM】代码理解

    本来想自己写一个EM算法的,但是操作没两步就进行不下去了.对那些数学公式着实不懂.只好从网上找找代码,看看别人是怎么做的. 代码:来自http://blog.sina.com.cn/s/blog_98 ...

  8. 如何将.il、.res文件封装成dll文件

    将你的.il..res文件保存在你的硬盘上,如下图: 我存放的路径在E盘的test文件夹中,我们开始封装了咯.进入DOS命令,如下图: 我们通过DOS命令先进入.il..res文件目录,如下图: 然后 ...

  9. C#文件夹和文件操作

    File.Exist(string path)//文件读写FileStream fs=new FileStream(filename, FileMode.Create);BinaryWriter bw ...

  10. 使用 ODBC .NET 提供程序和 Visual C# .NET 执行 SQL 参数化存储过程

    http://support2.microsoft.com/kb/310130/zh-cn 此分步指导文章描述如何使用 ODBC .NET 托管提供程序和 Visual C# .Net 调用参数化 S ...