题意我就不说了
 
解析: 莫队,先预处理出以i为右端点的区间的gcd值,有一些连续的区间的gcd值是相同的,比如[j,i],[j+1,i],[j+2,i]的gcd值是相同的,我们可以把[j,j+2]这个
区间保存下来。同时也预处理出以i为左端点的,最后用莫队算法。详见代码实现。
 
代码
  1. #include<cstdio>
  2. #include<vector>
  3. #include<cstring>
  4. #include<string>
  5. #include<cmath>
  6. #include<algorithm>
  7. using namespace std;
  8. const int maxn=;
  9. typedef __int64 LL;
  10. int N,M,A[maxn],block;
  11. struct Ques
  12. {
  13. int x,y,id;
  14. Ques(int x=,int y=,int id=):x(x),y(y),id(id){}
  15. bool operator < (const Ques& t) const
  16. {
  17. int a=x/block,b=t.x/block; //排序
  18. if(a!=b) return a<b;
  19. return y<t.y;
  20. }
  21. }ques[maxn];
  22. int gcd(int a,int b){ return b==?a:gcd(b,a%b); }
  23. struct node
  24. {
  25. int id,g;
  26. node(int id=,int g=):id(id),g(g){}
  27. };
  28. vector<node> vl[maxn],vr[maxn];
  29. void GetLe()
  30. {
  31. for(int i=;i<=N;i++) //得到以i为右端点连续区间的gcd值
  32. {
  33. if(i==){ vl[i].push_back(node(i,A[i])); continue; }
  34. int g=A[i],id=i;
  35. int Size=vl[i-].size();
  36. for(int j=;j<Size;j++)
  37. {
  38. node& t=vl[i-][j];
  39. int ng=gcd(t.g,g);
  40. if(ng!=g) vl[i].push_back(node(id,g));
  41. g=ng; id=t.id;
  42. }
  43. vl[i].push_back(node(id,g));
  44. }
  45. }
  46. void GetRi() //同理
  47. {
  48. for(int i=N;i>=;i--)
  49. {
  50. if(i==N){ vr[i].push_back(node(i,A[i])); continue; }
  51. int g=A[i],id=i;
  52. int Size=vr[i+].size();
  53. for(int j=;j<Size;j++)
  54. {
  55. node& t=vr[i+][j];
  56. int ng=gcd(t.g,g);
  57. if(ng!=g) vr[i].push_back(node(id,g));
  58. g=ng; id=t.id;
  59. }
  60. vr[i].push_back(node(id,g));
  61. }
  62. }
  63. LL WorkLe(int x,int y)
  64. {
  65. int Size=vl[y].size();
  66. int ny=y;
  67. LL ret=;
  68. for(int i=;i<Size;i++)
  69. {
  70. node& t=vl[y][i];
  71. if(t.id>=x)
  72. {
  73. ret+=(LL)t.g*(ny-t.id+);
  74. ny=t.id-; //跳过去
  75. }
  76. else{ ret+=(LL)t.g*(ny-x+); break; }
  77. }
  78. return ret;
  79. }
  80. LL WorkRi(int x,int y)
  81. {
  82. int nx=x;
  83. LL ret=;
  84. int Size=vr[x].size();
  85. for(int i=;i<Size;i++)
  86. {
  87. node& t=vr[x][i];
  88. if(t.id<=y)
  89. {
  90. ret+=(LL)t.g*(t.id-nx+);
  91. nx=t.id+;
  92. }
  93. else { ret+=(LL)t.g*(y-nx+); break; }
  94. }
  95. return ret;
  96. }
  97. LL ans[maxn];
  98. void solve()
  99. {
  100. for(int i=;i<=N;i++) vl[i].clear(),vr[i].clear();
  101. block=(int)sqrt(N+0.5); //分块
  102. sort(ques,ques+M); //排序
  103. GetLe(); //得到左边连续相同的gcd区间
  104. GetRi(); //得到右边连续相同的gcd区间
  105. int x=,y=;
  106. LL ret=;
  107. for(int i=;i<M;i++) //莫队的主要实现部分
  108. {
  109. Ques& q=ques[i];
  110. while(y<q.y){ y++; ret+=WorkLe(x,y); }
  111. while(y>q.y){ ret-=WorkLe(x,y); y--; }
  112. while(x<q.x){ ret-=WorkRi(x,y); x++; }
  113. while(x>q.x){ x--; ret+=WorkRi(x,y); }
  114. ans[q.id]=ret; //保存答案
  115. }
  116. for(int i=;i<M;i++) printf("%lld\n",ans[i]); //输出
  117. }
  118. int main()
  119. {
  120. int T;
  121. scanf("%d",&T);
  122. while(T--)
  123. {
  124. scanf("%d",&N);
  125. for(int i=;i<=N;i++) scanf("%d",&A[i]);//输入
  126. scanf("%d",&M);
  127. int x,y;
  128. for(int i=;i<M;i++)
  129. {
  130. scanf("%d%d",&x,&y);
  131. ques[i]=Ques(x,y,i); //离线保存查询
  132. }
  133. solve();
  134. }
  135. return ;
  136. }

Hdu5381-The sum of gcd(莫队)的更多相关文章

  1. hdu5381 The sum of gcd]莫队算法

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=5381 思路:这个题属于没有修改的区间查询问题,可以用莫队算法来做.首先预处理出每个点以它为起点向左和向右连 ...

  2. hdu 5381 The sum of gcd 莫队+预处理

    The sum of gcd Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) P ...

  3. hdu 4676 Sum Of Gcd 莫队+phi反演

    Sum Of Gcd 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4676 Description Given you a sequence of ...

  4. HDU-4676 Sum Of Gcd 莫队+欧拉函数

    题意:给定一个11~nn的全排列AA,若干个询问,每次询问给出一个区间[l,r][l,r],要求得出∑l≤i<j≤r  gcd(Ai,Aj)的值. 解法:这题似乎做的人不是很多,蒟蒻当然不会做只 ...

  5. hdu 4676 Sum Of Gcd 莫队+数论

    题目链接 给n个数, m个询问, 每个询问给出[l, r], 问你对于任意i, j.gcd(a[i], a[j]) L <= i < j <= R的和. 假设两个数的公约数有b1, ...

  6. HDOJ 5381 The sum of gcd 莫队算法

    大神题解: http://blog.csdn.net/u014800748/article/details/47680899 The sum of gcd Time Limit: 2000/1000 ...

  7. hdu5381 The sum of gcd

    莫队算法,预处理出每个数字往后的gcd情况,每个数字的gcd只可能是他的因子,因此后面最多只可能有logn种,可以先预处理出,然后套莫队算法,复杂度O(n*sqrt(n)*log(n)). 代码 #i ...

  8. [CSP-S模拟测试]:sum(数学+莫队)

    题目传送门(内部题63) 输入格式 第一行有一个整数$id$,表示测试点编号.第一行有一个整数$q$,表示询问组数.然后有$q$行,每行有两个整数$n_i,m_i$. 输出格式 一共有$q$行,每行一 ...

  9. HDU 4676 Sum Of Gcd 【莫队 + 欧拉】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=4676 Sum Of Gcd Time Limit: 10000/5000 MS (Java/Others ...

随机推荐

  1. x2engine

    x2engine 各版本下载 https://bitnami.com/stack/x2crm/installer https://bitnami.com/redirect/to/36211/bitna ...

  2. ext3中xtype属性汇总

    基本组件: xtype Class 描述 button Ext.Button 按钮 splitbutton Ext.SplitButton 带下拉菜单的按钮 cycle Ext.CycleButton ...

  3. J2EE学习路线

    第一部分:  JAVA语言基础知识.包括异常.IO流.多线程.集合类.数据库.(切记基础知识一定要时时刻刻巩固,注意,如果你是想以最快速度学习J2EE,关于Java中的Swing知识点,就只做了解)  ...

  4. eclipse java 配置

    1.eclipse菜单 - Window - Preferences- Java - Installed JREs 2.eclipse菜单 - Window - Preferences- Java - ...

  5. Javascript:作用域 学习总结

    作用域(scope): 变量与函数的可访问范围,控制着变量与函数的可见性和生命周期   作用域分类: javascript中,变量的作用域分为:全局作用域,局部作用域 局部变量的优先级大于全局变量,或 ...

  6. Oracle11g环境设置-windows环境

    新建环境变量(系统变量),变量名:ORACLE_HOME 变量值:E:\app\Administrator\product\11.2.0\dbhome_1 新建环境变量(系统变量),变量名:ORACL ...

  7. sqlserver2005重新安装(安装汇编错误,安装程序无法连接到数据库服务进行服务配置)

    2014-01-09 16:41 1687人阅读 评论(1) 收藏 举报 分类: 数据库(1) 版权声明:本文为博主原创文章,未经博主允许不得转载. sqlserver2005重新安装(安装汇编错误, ...

  8. jquery cookie 删除不了的处理办法

    $.cookie(name, null);$.cookie(name, null, {path : "/"}); Jquery Cookie的值直接设置null,并不能直接删除Co ...

  9. 关于(x&y)+((x^y)>>1)的探究

    今天在程序员面试宝典上看到 int f(int x int y ) { return (x&y)+((x^y)>>1) } f(729,271) 结果为500 从式子中可以看出分为 ...

  10. C#中KeyDown和KeyPress区别

    1.比如说TexBox 输入'a' 按下->触发KeyDown事件,然后去处理 ->将a显示输入到文本框后 ->触发KeyPress事件