Different GCD Subarray Query

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

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
  1. /*
  2. hdu 5869 区间不同GCD个数(树状数组)
  3.  
  4. problem:
  5. 给你一组数, 然后是q个查询. 问[l,r]中所有区间GCD的值总共有多少个(不同的)
  6.  
  7. solve:
  8. 感觉很像线段树/树状数组. 因为有很多题都是枚举从小到大处理查询的r. 这样的话就只需要维护[1,i]的情况
  9. 最开始用的set记录生成的gcd然后递推, 超时了.
  10. 因为区间gcd是有单调性的. (i-1->1)和i区间gcd是递减的.
  11. 而且用RMQ可以O(1)的查询[i,j]gcd的值.如果枚举[1,i-1]感觉很麻烦.所以用二分跳过中间gcd值相同的部分,即查询与i的区间gcd值为x的
  12. 最左边端点.
  13.  
  14. 因为要求不同的值, 这让我想到了用线段树求[l,r]中不同数的个数(忘了是哪道题了 zz)
  15. 就i而言,首先找出最靠近i的位置使gcd的值为x. 然后和以前的位置作比较. 尽可能的维护这个位置靠右.
  16. 假设:
  17. [3,i-1]的gcd为3,[2,i]的gcd为3. 那么在位置3上面加1.因为只要[l,i]包含这个点,那么就会有3这个值.
  18.  
  19. hhh-2016-09-10 19:01:57
  20. */
  21. #include <algorithm>
  22. #include <iostream>
  23. #include <cstdlib>
  24. #include <stdio.h>
  25. #include <cstring>
  26. #include <vector>
  27. #include <math.h>
  28. #include <queue>
  29. #include <set>
  30. #include <map>
  31. #define ll long long
  32.  
  33. using namespace std;
  34.  
  35. const int maxn = 100100;
  36.  
  37. int a[maxn];
  38. map<ll,int>mp;
  39.  
  40. struct node
  41. {
  42. int l,r;
  43. int id;
  44. } p[maxn];
  45.  
  46. bool tocmp(node a,node b)
  47. {
  48. if(a.r != b.r)
  49. return a.r < b.r;
  50. if(a.l != b.l)
  51. return a.l < b.l;
  52. }
  53.  
  54. ll Gcd(ll a,ll b)
  55. {
  56. if(b==0) return a;
  57. else return Gcd(b,a%b);
  58. }
  59.  
  60. int lowbit(int x)
  61. {
  62. return x&(-x);
  63. }
  64.  
  65. ll out[maxn];
  66. ll siz[maxn];
  67.  
  68. int n;
  69. void add(int x,ll val)
  70. {
  71. if(x <= 0)
  72. return ;
  73. while(x <= n)
  74. {
  75. siz[x] += val;
  76. x += lowbit(x);
  77. }
  78. }
  79.  
  80. ll sum(int x)
  81. {
  82. if(x <=0)
  83. return 0;
  84. ll cnt = 0;
  85. while(x > 0)
  86. {
  87. cnt += siz[x];
  88. x -= lowbit(x);
  89. }
  90. return cnt;
  91. }
  92.  
  93. int dp[maxn][40];
  94. int m[maxn];
  95.  
  96. int RMQ(int x,int y)
  97. {
  98. int t = m[y-x+1];
  99. return Gcd(dp[x][t],dp[y-(1<<t)+1][t]);
  100. }
  101.  
  102. void iniRMQ(int n,int c[])
  103. {
  104. m[0] = -1;
  105. for(int i = 1; i <= n; i++)
  106. {
  107. m[i] = ((i&(i-1)) == 0)? m[i-1]+1:m[i-1];
  108. dp[i][0] = c[i];
  109. }
  110. for(int j = 1; j <= m[n]; j++)
  111. {
  112. for(int i = 1; i+(1<<j)-1 <= n; i++)
  113. dp[i][j] = Gcd(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
  114. }
  115. }
  116.  
  117. void init()
  118. {
  119. mp.clear();
  120. memset(siz,0,sizeof(siz));
  121. iniRMQ(n,a);
  122. }
  123.  
  124. int main()
  125. {
  126. int qry;
  127. while(scanf("%d",&n) != EOF)
  128. {
  129. scanf("%d",&qry);
  130.  
  131. for(int i = 1; i<=n; i++)
  132. {
  133. scanf("%d",&a[i]);
  134. }
  135. init();
  136. for(int i = 0; i < qry; i++)
  137. {
  138. scanf("%d",&p[i].l),scanf("%d",&p[i].r),p[i].id = i;
  139. }
  140. int ta = 0;
  141. sort(p, p+qry, tocmp);
  142.  
  143. for(int i = 1; i <= n; i++)
  144. {
  145. int thea = a[i];
  146. int j = i;
  147. while(j >= 1)
  148. {
  149. int tmid = j;
  150. int l = 1,r = j;
  151.  
  152. while(l <= r)
  153. {
  154. int mid = (l+r) >> 1;
  155. if(l == r && RMQ(mid,i) == thea)
  156. {
  157. tmid = mid;
  158. break;
  159. }
  160.  
  161. if(RMQ(mid,i) == thea)
  162. r = mid-1,tmid = mid;
  163. else
  164. l = mid+1;
  165. }
  166.  
  167. if(!mp[thea])
  168. add(j,1);
  169. else if(mp[thea] < j && mp[thea])
  170. {
  171. add(mp[thea],-1);
  172. add(j,1);
  173. }
  174. mp[thea] = j;
  175.  
  176. j = tmid-1;
  177.  
  178. if(j >= 1) thea = RMQ(j,i);
  179. }
  180.  
  181. while(ta < qry && p[ta].r == i)
  182. {
  183. out[p[ta].id] = sum(p[ta].r) - sum(p[ta].l-1);
  184. ta++;
  185. }
  186.  
  187. }
  188.  
  189. for(int i = 0; i < qry; i++)
  190. printf("%I64d\n",out[i]);
  191. }
  192. return 0;
  193. }

  

  

hdu 5869 区间不同GCD个数(树状数组)的更多相关文章

  1. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...

  2. hdu 6203 ping ping ping(LCA+树状数组)

    hdu 6203 ping ping ping(LCA+树状数组) 题意:给一棵树,有m条路径,问至少删除多少个点使得这些路径都不连通 \(1 <= n <= 1e4\) \(1 < ...

  3. hdu 5877 Weak Pair dfs序+树状数组+离散化

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Prob ...

  4. FZU2224 An exciting GCD problem 区间gcd预处理+树状数组

    分析:(别人写的) 对于所有(l, r)区间,固定右区间,所有(li, r)一共最多只会有log个不同的gcd值, 可以nlogn预处理出所有不同的gcd区间,这样区间是nlogn个,然后对于询问离线 ...

  5. hdu 1754 I Hate It(树状数组区间求最值)2007省赛集训队练习赛(6)_linle专场

    题意: 输入一行数字,查询第i个数到第j个数之间的最大值.可以修改其中的某个数的值. 输入: 包含多组输入数据. 每组输入首行两个整数n,m.表示共有n个数,m次操作. 接下来一行包含n个整数. 接下 ...

  6. hdu 1116 敌兵布阵(树状数组区间求和)

    题意: 给出一行数字,然后可以修改其中第i个数字,并且可以询问第i至第j个数字的和(i <= j). 输入: 首行输入一个t,表示共有t组数据. 接下来每行首行输入一个整数n,表示共有n个数字. ...

  7. 2016 大连网赛---Different GCD Subarray Query(GCD离散+树状数组)

    题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5869 Problem Description This is a simple probl ...

  8. HDU 4746 莫比乌斯反演+离线查询+树状数组

    题目大意: 一个数字组成一堆素因子的乘积,如果一个数字的素因子个数(同样的素因子也要多次计数)小于等于P,那么就称这个数是P的幸运数 多次询问1<=x<=n,1<=y<=m,P ...

  9. POJ 3928 &amp; hdu 2492 &amp; Uva1428 PingPong 【树状数组】

    Ping pong                                                   Time Limit: 2000/1000 MS (Java/Others)   ...

随机推荐

  1. 201621123057 《Java程序设计》第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以被多个用户通过网 ...

  2. python的Collections 模块

    Collections 模块 知识点 Counter 类 defaultdict 类 namedtuple 类 在这个实验我们会学习 Collections 模块.这个模块实现了一些很好的数据结构,它 ...

  3. bzoj 4373 算术天才⑨与等差数列

    4373: 算术天才⑨与等差数列 Time Limit: 10 Sec  Memory Limit: 128 MBhttp://www.lydsy.com/JudgeOnline/problem.ph ...

  4. HTML 字符集

    在 HTML 中,正确的字符编码是什么?   HTML5 中默认的字符编码是 UTF-8. 这并非总是如此.早期网络的字符编码是 ASCII 码.后来,从 HTML 2.0 到 HTML 4.01,I ...

  5. OpenGL中怎么把世界坐标系变成屏幕坐标系

    对这个3D坐标手动进行OpenGL的四个变换,得到的结果就是屏幕上的像素坐标.前三个变换(Model, View, Projection)都是4x4矩阵,操作对象是四维向量,所以需要把(100, 10 ...

  6. ASP.NET MVC5 Forms登陆+权限控制(控制到Action)

    一.Forms认证流程 请先参考如下网址: http://www.cnblogs.com/fish-li/archive/2012/04/15/2450571.html 本文主要介绍使用自定义的身份认 ...

  7. 转:NLP+句法结构(三)︱中文句法结构(CIPS2016、依存句法、文法)

    NLP+句法结构(三)︱中文句法结构(CIPS2016.依存句法.文法)转自:https://www.cnblogs.com/maohai/p/6453389.html 摘录自:CIPS2016 中文 ...

  8. python中的进程池:multiprocessing.Pool()

    python中的进程池: 我们可以写出自己希望进程帮助我们完成的任务,然后把任务批量交给进程池 进程池帮助我们创建进程完成任务,不需要我们管理.进程池:利用multiprocessing 下的Pool ...

  9. MYSQL之索引原理与慢查询优化

    一.索引 1.介绍 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的也是最容易出现问题的,还是一些复杂的查询操作,因此对查询语句的优化 ...

  10. python基础——抽象类

    python基础--抽象类 1  什么是抽象类 与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化 2 为什么要有抽象 ...