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个数Q个查询,每次查询询问[l,r]内不同gcd的个数
**思路:**Q很大,按照一般思路使用线段树在线操作似乎不可行,所以考虑使用离线操作。但重点在于如何预处理出GCD。
在这里我们固定右端点,枚举上一个端点所存的所有不同GCD值,求GCD,并记录不同的,延伸右端点时,再重复操作即可。
在树状数组更新时,当出现一个重复的GCD值,始终把标记维护到最靠右的,并把之前出现的相同GCD的位置所在的标记消掉。这样就能使数量数组拥有前缀特性,可以使用sum[r]-sum[l]了
容器套容器很好用阿,弱要加快学了。

  1. /** @Date : 2016-11-13-16.10

  2. * @Author : Lweleth (SoungEarlf@gmail.com)

  3. * @Link : https://github.com/

  4. * @Version :

  5. */

  6. #include <stdio.h>

  7. #include <iostream>

  8. #include <string.h>

  9. #include <algorithm>

  10. #include <utility>

  11. #include <vector>

  12. #include <map>

  13. #include <set>

  14. #include <string>

  15. #include <stack>

  16. #include <queue>

  17. #define pii pair<int , int>

  18. #define FF first

  19. #define SS second

  20. #define MP(x,y) make_pair((x), (y))

  21. #define LL long long

  22. #define MMF(x) memset((x),0,sizeof(x))

  23. #define MMI(x) memset((x), INF, sizeof(x))

  24. using namespace std;



  25. const int INF = 0x3f3f3f3f;

  26. const int N = 1e5+2000;



  27. int n,q;

  28. int c[N];

  29. int a[N];

  30. int ans[N];

  31. vector< pair<int,int> >gp[N];

  32. int vis[1000010];



  33. struct yuu

  34. {

  35. int l, r;

  36. int m;

  37. }Q[N];



  38. int cmp(yuu a, yuu b)

  39. {

  40. return a.r < b.r;

  41. }

  42. int gcd(int a, int b)

  43. {

  44. return b?gcd(b, a % b):a;

  45. }



  46. void add(int x, int y)

  47. {

  48. while(x < N)

  49. {

  50. c[x] += y;

  51. x += x & (-x);

  52. }

  53. }



  54. int sum(int x)

  55. {

  56. int ans = 0;

  57. while(x)

  58. {

  59. ans += c[x];

  60. x -= x & (-x);

  61. }

  62. return ans;

  63. }



  64. void init()

  65. {



  66. MMF(c);

  67. MMF(vis);

  68. MMF(ans);

  69. for(int i = 1; i <= n; i++)

  70. {

  71. int x = a[i];

  72. int p = i;

  73. for(int j = 0; j < gp[i-1].size(); j++)

  74. {

  75. int g = gcd(gp[i-1][j].FF, x);

  76. if(x != g)

  77. {

  78. gp[i].push_back(MP(x, p));

  79. x = g;

  80. p = gp[i-1][j].SS;

  81. }

  82. }

  83. gp[i].push_back(MP(x, p));

  84. }

  85. }

  86. int main()

  87. {

  88. while(~scanf("%d%d", &n, &q))

  89. {



  90. MMF(a);

  91. for(int i = 1; i <= n; i++ )

  92. {

  93. scanf("%d", a + i);

  94. gp[i].clear();

  95. }

  96. init();

  97. for(int i = 0; i < q; i++)

  98. {

  99. scanf("%d%d", &Q[i].l, &Q[i].r);

  100. Q[i].m = i;

  101. }



  102. sort(Q, Q + q, cmp);

  103. //////

  104. int pos = 0;

  105. for(int i = 1; i <= n; i++)

  106. {

  107. for(int j = 0; j < gp[i].size(); j++)//

  108. {

  109. if(vis[gp[i][j].FF])

  110. add(vis[gp[i][j].FF], -1);

  111. vis[gp[i][j].FF] = gp[i][j].SS;

  112. add(gp[i][j].SS, 1);

  113. }

  114. while(Q[pos].r == i)

  115. {

  116. ans[Q[pos].m] = sum(Q[pos].r) - sum(Q[pos].l-1);

  117. pos++;

  118. }

  119. }

  120. for(int i = 0; i < q; i++)

  121. printf("%d\n", ans[i]);



  122. }

  123. return 0;

  124. }

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

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

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

  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 (GCD种类预处理+树状数组维护)

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

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

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

  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 4630 No Pain No Game 树状数组+离线查询

    思路参考 这里. #include <cstdio> #include <cstring> #include <cstdlib> #include <algo ...

  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. 【转】Hbuilder MUI 页面刷新及页面传值问题

    文章来源:http://www.111cn.net/sys/CentOS/67213.htm 一.页面刷新问题 1.父页面A跳转到子页面B,B页面修改数据后再跳回A页面,刷新A页面数据 (1).父页面 ...

  2. NFC进场通信总结概述

    简介 本文介绍Nokia设备所支持的近场通信技术(NFC)及相关的功能.旨在为使用 Qt/Symbian/Java™ API为Nokia手机开发应用的开发者 刚开始接触NFC开发时提供有用的信息. 什 ...

  3. 数据库集群之路二 MYCAT

    windows下安装配置并使用mycat 参考:http://www.cnblogs.com/parryyang/p/5758087.html 一 下载windows版本 https://github ...

  4. How To Disable MacBook ProTrackpad

    How To Disable MacBook Pro Trackpad how to close macbook pro touchpad? https://www.wikihow.com/Chang ...

  5. [STL] 如何将一个vector赋给另一个vector

    vector 有个函数assign, 可以帮助执行赋值操作. assign会清空你的容器. assign函数: 函数原型: void assign(const_iterator first,const ...

  6. TScreen 类

    TScreen表示应用程序运行时屏幕的状态. 类关系 TObject->TPersistent->TComponent TScreen引进具有表示下列各种情况的属性 什么窗体和数据模块已经 ...

  7. 能选择日期范围js控件

    html页面中使用日期控件是常有的事,好控件能使用开发变的快捷,下面是在开发过程中发现的几款日期控件,比较不错,收藏 1.基于bootstrap的jQuery日期范围选择插件 2.jQuery多功能日 ...

  8. POJ3335:Rotating Scoreboard——题解

    http://poj.org/problem?id=3335 题目大意:给按照顺时针序的多边形顶点,问其是否有内核. —————————————————————————————— 看了两个小时的资料, ...

  9. POJ3977:Subset——题解(三分+折半搜索)

    http://poj.org/problem?id=3977 题目大意:有一堆数,取出一些数,记他们和的绝对值为w,取的个数为n,求在w最小的情况下,n最小,并输出w,n. ————————————— ...

  10. BZOJ2668:[CQOI2012]交换棋子——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2668 https://www.luogu.org/problemnew/show/P3159#sub ...