hdu 5381 The sum of gcd(线段树)
2016-05-28 14:33
459 查看
The sum of gcd
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1056 Accepted Submission(s): 465
Problem Description
You have an array A,the
length of A is n
Let f(l,r)=∑ri=l∑rj=igcd(ai,ai+1....aj)
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
First line has one integers n
Second line has n integers Ai
Third line has one integers Q,the
number of questions
Next there are Q lines,each line has two integers l,r
1≤T≤3
1≤n,Q≤104
1≤ai≤109
1≤l<r≤n
Output
For each question,you need to print f(l,r)
Sample Input
2
5
1 2 3 4 5
3
1 3
2 3
1 4
4
4 2 6 9
3
1 3
2 4
2 3
Sample Output
9
6
16
18
23
10
Author
SXYZ
#include<cstdio> #include<algorithm> using namespace std; #define ls t<<1 #define rs (t<<1)|1 const int maxn = 1e4 + 200; int val[maxn],n, m; struct node { int lg[32], rg[32], ln[32], rn[32], cntl, cntr; long long sum; }tree[maxn<<2],ans; int gcd(int a, int b) { if (b == 0)return a; return gcd(b, a%b); } node Union(node a, node b) { node ret; ret.sum = a.sum + b.sum; for (int i = 0; i < a.cntr; i++) for (int j = 0; j < b.cntl; j++) ret.sum += 1ll * gcd(a.rg[i], b.lg[j])*a.rn[i] * b.ln[j]; for (int i = 0; i < a.cntl; i++) { ret.lg[i] = a.lg[i]; ret.ln[i] = a.ln[i]; } for (int i = 0; i < b.cntr; i++) { ret.rg[i] = b.rg[i]; ret.rn[i] = b.rn[i]; } int d = b.rg[b.cntr - 1], pos = b.cntr; for (int i = 0; i < a.cntr; i++) { int tmp = gcd(d, a.rg[i]); if (tmp == ret.rg[pos - 1])ret.rn[pos - 1] += a.rn[i]; else { ret.rg[pos] = tmp; ret.rn[pos++] = a.rn[i]; } } ret.cntr = pos; d = a.lg[a.cntl - 1], pos = a.cntl; for (int i = 0; i < b.cntl; i++) { int tmp = gcd(d, b.lg[i]); if (tmp == ret.lg[pos - 1])ret.ln[pos - 1] += b.ln[i]; else { ret.lg[pos] = tmp; ret.ln[pos++] = b.ln[i]; } } ret.cntl = pos; return ret; } void build(int l, int r, int t) { if (l == r) { tree[t].cntl = tree[t].cntr = 1; tree[t].sum = tree[t].rg[0] = tree[t].lg[0] = val[l]; tree[t].ln[0] = tree[t].rn[0] = 1; return; } build(l, (l + r) / 2, ls); build((l + r) / 2 + 1, r, rs); tree[t] = Union(tree[ls], tree[rs]); } void query(int l, int r,int lt,int rt, int t) { if (lt<=l&&rt>=r) { if (lt==l)ans = tree[t]; else ans=Union(ans, tree[t]); return; } int mid = (l+r) / 2; if (lt <= mid)query(l,mid,lt,rt, ls); if (rt > mid)query(mid+1,r,lt,rt, rs); } int main() { int t,l,r; scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &val[i]); build(1, n, 1); scanf("%d", &m); while (m--) { scanf("%d%d", &l, &r); query(1,n,l,r,1); printf("%I64d\n", ans.sum); } } return 0; }
相关文章推荐
- iOS 常用技术 — 获取手机基本信息
- Android camare 的使用
- MD5加密算法的识别
- 中山劳务派遣服务介绍
- ffmpeg打开视频文件步骤
- 字符串逆向输出
- Etcd操作简单介绍
- ZOJ 3811 dfs&并查集
- mysql MHA高可用架构搭建部署实验
- mprotect()函数 Unix/Linux
- hdu-2829 Lawrence[斜率dp]
- 博客前端
- permulation and review
- 7. Reverse Integer
- 其实我想说,如果你用了eventBus,那么你进来看看吧...
- 对象的序列化
- python-布尔值
- 网格 [Bzoj 3907]
- Oralce decode函数用法示例
- javascript、jQuery操作数组