题意:http://acm.hdu.edu.cn/showproblem.php?pid=5381

思路:这个题属于没有修改的区间查询问题,可以用莫队算法来做。首先预处理出每个点以它为起点向左和向右连续一段的gcd发生变化的每个位置,不难发现对每个点A[i],这样的位置最多logA[i]个,这可以利用ST表用nlognlogA[i]的时间预处理,然后用二分+RMQ在nlogn的时间内得到。然后就是区间变化为1时的转移了,不难发现区间变化为1时,变化的答案仅仅是以变化的那一个点作为左端点或右端点的连续子串的gcd的和,而这个gcd最多logA[i]种,利用前面的预处理可以在logA[i]的时间内累加得到答案。总复杂度O(NlogNlogA[i]+N√NlogA[i])

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
  98. 98
  99. 99
  100. 100
  101. 101
  102. 102
  103. 103
  104. 104
  105. 105
  106. 106
  107. 107
  108. 108
  109. 109
  110. 110
  111. 111
  112. 112
  113. 113
  114. 114
  115. 115
  116. 116
  117. 117
  118. 118
  119. 119
  120. 120
  121. 121
  122. 122
  123. 123
  124. 124
  125. 125
  126. 126
  127. 127
  128. 128
  129. 129
  130. 130
  131. 131
  132. 132
  133. 133
  134. 134
  135. 135
  136. 136
  137. 137
  138. 138
  139. 139
  140. 140
  141. 141
  142. 142
  143. 143
  144. 144
  145. 145
  146. 146
  147. 147
  148. 148
  149. 149
  150. 150
  151. 151
  152. 152
  153. 153
  154. 154
  155. 155
  156. 156
  157. 157
  158. 158
  159. 159
  160. 160
  161. 161
  162. 162
  163. 163
  164. 164
  165. 165
  166. 166
  167. 167
  168. 168
  169. 169
  170. 170
  171. 171
  172. 172
  173. 173
  174. 174
  175. 175
  176. 176
  177. 177
  178. 178
  179. 179
  180. 180
  181. 181
  182. 182
  183. 183
  184. 184
  185. 185
  186. 186
  187. 187
  188. 188
  189. 189
  190. 190
  191. 191
  192. 192
  193. 193
  1. #include <map>
  2. #include <set>
  3. #include <cmath>
  4. #include <ctime>
  5. #include <deque>
  6. #include <queue>
  7. #include <stack>
  8. #include <vector>
  9. #include <cstdio>
  10. #include <string>
  11. #include <cstdlib>
  12. #include <cstring>
  13. #include <iostream>
  14. #include <algorithm>
  15.  
  16. using namespace std;
  17.  
  18. #define X first
  19. #define Y second
  20. #define pb push_back
  21. #define mp make_pair
  22. #define all(a) (a).begin(), (a).end()
  23. #define fillchar(a, x) memset(a, x, sizeof(a))
  24. #define copy(a, b) memcpy(a, b, sizeof(a))
  25.  
  26. typedef long long ll;
  27. typedef pair<int, int> pii;
  28. typedef unsigned long long ull;
  29.  
  30. //#ifndef ONLINE_JUDGE
  31. void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
  32. void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
  33. void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
  34. while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
  35. void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
  36. void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
  37. void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
  38. //#endif
  39. template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
  40. template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
  41.  
  42. const double PI = acos(-1.0);
  43. const int INF = 1e9 + ;
  44. const double EPS = 1e-8;
  45.  
  46. /* -------------------------------------------------------------------------------- */
  47.  
  48. const int maxn = 1e4 + ;
  49.  
  50. int gcd(int a, int b) {
  51. return b? gcd(b, a % b) : a;
  52. }
  53.  
  54. struct ST {
  55. int dp[maxn][];
  56. int index[maxn];
  57. void init_index() {
  58. index[] = ;
  59. for (int i = ; i < maxn; i ++) {
  60. index[i] = index[i - ];
  61. if (!(i & (i - ))) index[i] ++;
  62. }
  63. }
  64. void init_gcd(int a[], int n) {
  65. for (int i = ; i < n; i ++) dp[i][] = a[i];
  66. for (int j = ; ( << j) <= n; j ++) {
  67. for (int i = ; i + ( << j) - < n; i ++) {
  68. dp[i][j] = gcd(dp[i][j - ], dp[i + ( << (j - ))][j - ]);
  69. }
  70. }
  71. }
  72.  
  73. int query_gcd(int L, int R) {
  74. int p = index[R - L + ];
  75. return gcd(dp[L][p], dp[R - ( << p) + ][p]);
  76. }
  77. };
  78. ST st;
  79.  
  80. int n, q, block;
  81. int a[maxn];
  82. vector<int> L[maxn], R[maxn];
  83. pair<pii, int> b[maxn];
  84.  
  85. bool cmp(const pair<pii, int> &a, const pair<pii, int> &b) {
  86. int lb = a.X.X / block, rb = b.X.X / block;
  87. return lb == rb? a.X.Y < b.X.Y : lb < rb;
  88. }
  89.  
  90. void init() {
  91. for (int i = ; i < n; i ++) {
  92. L[i].clear();
  93. R[i].clear();
  94. }
  95. for (int i = ; i < n; i ++) {
  96. int u = i;
  97. R[i].pb(i - );
  98. while (u < n) {
  99. int l = u, r = n - ;
  100. while (l < r) {
  101. int m = (l + r + ) >> ;
  102. if (st.query_gcd(i, m) == st.query_gcd(i, u)) l = m;
  103. else r = m - ;
  104. }
  105. u = l + ;
  106. R[i].pb(l);
  107. }
  108. }
  109. for (int i = ; i < n; i ++) {
  110. int u = i;
  111. L[i].pb(i + );
  112. while (u >= ) {
  113. int l = , r = u;
  114. while (l < r) {
  115. int m = (l + r) >> ;
  116. if (st.query_gcd(m, i) == st.query_gcd(u, i)) r = m;
  117. else l = m + ;
  118. }
  119. u = l - ;
  120. L[i].pb(l);
  121. }
  122. }
  123. }
  124.  
  125. ll f(int l, int r) {
  126. ll ans = ;
  127. for (int i = ; i < R[l].size(); i ++) {
  128. if (r <= R[l][i]) return ans + (ll)(r - R[l][i - ]) * st.query_gcd(l, r);
  129. ans += (ll)(R[l][i] - R[l][i - ]) * st.query_gcd(l, R[l][i]);
  130. }
  131. }
  132.  
  133. ll g(int l, int r) {
  134. ll ans = ;
  135. for (int i = ; i < L[r].size(); i ++) {
  136. if (l >= L[r][i]) return ans + (ll)(L[r][i - ] - l) * st.query_gcd(l, r);
  137. ans += (ll)(L[r][i - ] - L[r][i]) * st.query_gcd(L[r][i], r);
  138. }
  139. }
  140.  
  141. int main() {
  142. #ifndef ONLINE_JUDGE
  143. freopen("in.txt", "r", stdin);
  144. //freopen("out.txt", "w", stdout);
  145. #endif // ONLINE_JUDGE
  146. int T;
  147. cin >> T;
  148. st.init_index();
  149. while (T --) {
  150. cin >> n;
  151. block = (int)sqrt(n + 0.1);
  152. for (int i = ; i < n; i ++) {
  153. scanf("%d", a + i);
  154. }
  155. st.init_gcd(a, n);
  156. init();
  157. cin >> q;
  158. for (int i = ; i < q; i ++) {
  159. scanf("%d%d", &b[i].X.X, &b[i].X.Y);
  160. b[i].X.X --;
  161. b[i].X.Y --;
  162. b[i].Y = i;
  163. }
  164. sort(b, b + q, cmp);
  165. vector<ll> ans(q);
  166. ll lastans = a[];
  167. int lastl = , lastr = ;
  168. /** 注意区间变化的顺序,优先考虑扩大区间,保证任何时刻区间不为负 */
  169. for (int i = ; i < q; i ++) {
  170. while (lastl > b[i].X.X) {
  171. lastl --;
  172. lastans += f(lastl, lastr);
  173. }
  174. while (lastr < b[i].X.Y) {
  175. lastr ++;
  176. lastans += g(lastl, lastr);
  177. }
  178. while (lastl < b[i].X.X) {
  179. lastans -= f(lastl, lastr);
  180. lastl ++;
  181. }
  182. while (lastr > b[i].X.Y) {
  183. lastans -= g(lastl, lastr);
  184. lastr --;
  185. }
  186. ans[b[i].Y] = lastans;
  187. }
  188. for (int i = ; i < q; i ++) {
  189. printf("%I64d\n", ans[i]);
  190. }
  191. }
  192. return ;
  193. }

hdu5381 The sum of gcd]莫队算法的更多相关文章

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

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

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

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

  3. Hdu5381-The sum of gcd(莫队)

    题意我就不说了   解析: 莫队,先预处理出以i为右端点的区间的gcd值,有一些连续的区间的gcd值是相同的,比如[j,i],[j+1,i],[j+2,i]的gcd值是相同的,我们可以把[j,j+2] ...

  4. 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 ...

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

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

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

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

  7. HDU5381【莫队算法+区间GCD特性】

    前言: 主要最近在刷莫队的题,这题GCD的特性让我对莫队的使用也有了新的想法.给福利:神犇的一套莫队算法题 先撇开题目,光说裸的一个莫队算法,主要的复杂度就是n*sqrt(n)对吧,这里我忽略了一个左 ...

  8. HDU 5381 The sum of gcd (技巧,莫队算法)

    题意:有一个含n个元素的序列,接下来有q个询问区间,对每个询问区间输出其 f(L,R) 值. 思路: 天真单纯地以为是道超级水题,不管多少个询问,计算量顶多就是O(n2) ,就是暴力穷举每个区间,再直 ...

  9. 【BZOJ】2038: [2009国家集训队]小Z的袜子(hose)(组合计数+概率+莫队算法+分块)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2038 学了下莫队,挺神的orzzzz 首先推公式的话很简单吧... 看的题解是从http://for ...

随机推荐

  1. ROM定制开发教程-Android adb命令用法与实例解析

    一.什么是ADB Android Debug Bridge(adb)是一个命令行工具,可让您与模拟器或连接的Android设备进行通信.您可以在android sdk / platform-tools ...

  2. mapstruct使用详解

    我们都知道,随着一个工程的越来越成熟,模块划分会越来越细,其中实体类一般存于 domain 之中,但 domain 工程最好不要被其他工程依赖,所以其他工程想获取实体类数据时就需要在各自工程写 mod ...

  3. Springboot:员工管理之环境准备(十(1))

    1:静态资源 下载静态资源:https://files.cnblogs.com/files/applesnt/ztzy.zip 项目下载:https://files.cnblogs.com/files ...

  4. 聊聊Spring Boot Actuator

    概述 在本文中,我们将介绍Spring Boot Actuator.我们将首先介绍基础知识,然后详细讨论Spring Boot 1.x和2.x中的可用内容. 我们将在Spring Boot 1.x中学 ...

  5. 十六, Oracle约束

    前言 数据的完整性用于确保数据库数据遵从一定的商业和逻辑规则,在oracle中,数据完整性可以使用约束.触发器.应用程序(过程.函数)三种方法来实现,在这三种方法中,因为约束易于维护,并且具有最好的性 ...

  6. mysql备份及恢复

    第四章:MySQL数据库的备份与恢复                            2016-09-30 00:58:05 标签:数据库备份 工作原理 数据库表 mysql source 原创 ...

  7. 也许你对 Fetch 了解得不是那么多(下)

    上文链接:也许你对 Fetch 了解得不是那么多(上) 编者按:除创宇前端与作者博客外,本文还在语雀发布. 编者还要按:作者也在掘金哦,欢迎关注:@GoDotDotDot Fetch 与 XHR 比较 ...

  8. 啃算法:归并排序及JavaScript实现

    在学习归并排序之前,有必要了解分治法,因为归并排序正是应用了分治模式.(基本定义摘自<算法导论>) 一.分治法 1.思想: 将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些 ...

  9. .NET Core+WebApi+EF访问数据新增用户数据

    新建一个.NET Core项目,我使用的IDE是VS2019 依次创建三个Core类库:第一个命名api.Model,第二个api.Common,第三个api.Bo 解释一下这个三类库的作用: 第一个 ...

  10. Hadoop学习笔记(二)——插件安装和使用(Hadoop Eclipse)

    1. Hadoop Eclipse @ 配置 需注意 在写Hadoop的根目录时,路径不能有空格 http://blog.sina.com.cn/s/blog_56d8111101014mlg.htm ...