HDU 5381The sum of gcd 莫队算法
来源:互联网 发布:网络研修收获与反思 编辑:程序博客网 时间:2024/05/20 20:22
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5381
题意:给定一个数组,每次询问给出l和r,求出
思路:看的大牛的代码,心累
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <vector>#define debug() puts("here")using namespace std;typedef long long ll;const int N = 10010;struct node{ int l, r, id;} g[N];int n, m, unit;ll res[N], tmp;int a[N], b[N], c[N];struct vv{ int id, g;};vector<vv> vec1[N], vec2[N];int gcd(int a, int b){ return !b ? a : gcd(b, a % b);}bool cmp(node a, node b){ return a.l/unit != b.l/unit ? a.l/unit < b.l/unit : a.r < b.r;}void work(){ for(int i = 1; i <= n; i++) vec1[i].clear(), vec2[i].clear(); for(int i = 1; i <= n; i++) { if(i == 1) vec1[i].push_back(vv{i, a[i]}); else { int curg = a[i], id = i; for(auto &it : vec1[i-1]) { int g = gcd(curg, it.g); if(g != curg) vec1[i].push_back(vv{id, curg}); curg = g, id = it.id; } vec1[i].push_back(vv{id, curg}); } } for(int i = n; i >= 1; i--) { if(i == n) vec2[i].push_back(vv{i, a[i]}); else { int curg = a[i], id = i; for(auto &it : vec2[i+1]) { int g = gcd(curg, it.g); if(g != curg) vec2[i].push_back(vv{id, curg}); curg = g, id = it.id; } vec2[i].push_back(vv{id, curg}); } }}ll calr(int l, int r){ ll sum = 0; int tr = r; for(auto &it : vec1[r]) if(it.id >= l) { sum += (ll)(tr - it.id + 1) * it.g; tr = it.id - 1; } else { sum += (ll)(tr - l + 1) * it.g; break; } return sum;}ll call(int l, int r){ ll sum = 0; int tl = l; for(auto &it : vec2[l]) if(it.id <= r) { sum += (ll)(it.id - tl + 1) * it.g; tl = it.id + 1; } else { sum += (ll)(r - tl + 1) * it.g; break; } return sum;}void solve(){ unit = (int)sqrt(1.0 * n); sort(g+1, g+1+m, cmp); int l = 1, r = 0; tmp = 0; for(int i = 1; i <= m; i++) { while(r < g[i].r) tmp += calr(l, ++r); while(r > g[i].r) tmp -= calr(l, r--); while(l < g[i].l) tmp -= call(l++, r); while(l > g[i].l) tmp += call(--l, r); res[g[i].id] = tmp; } for(int i = 1; i <= m; i++) printf("%lld\n", res[i]);}int main(){ int t; scanf("%d", &t); while(t--) { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); scanf("%d", &m); for(int i = 1; i <= m; i++) scanf("%d%d", &g[i].l, &g[i].r), g[i].id = i; work(); solve(); } return 0;}
0 0
- HDU 5381The sum of gcd 莫队算法
- hdu 5381 The sum of gcd 莫队算法+区间gcd
- HDU 5381(The sum of gcd-莫队算法解决区间段gcd的和)
- 莫队算法,gcd(The sum of gcd,HDU 5381)
- hdu 5381 The sum of gcd 2015多校联合训练赛#8莫队算法
- HDU 5381 The sum of gcd(数论+莫队算法)
- HDU 5381 The sum of gcd 莫队暴力
- HDOJ 5381 The sum of gcd 莫队算法
- HDU 5381 The sum of gcd 询问区间内所有子区间的GCD和 [莫队算法]
- HDU 5381 The sum of gcd
- hdu 5381 The sum of gcd
- hdu 5381 The sum of gcd
- HDU 5381The sum of gcd
- HDU 5381 The sum of gcd
- HDU 5381 The sum of gcd
- HDU 5381 The sum of gcd
- [反演 莫队算法] HDU 4676 Sum Of Gcd
- hdu 5381 The sum of gcd(线段树+gcd)
- 2017届毕业生安卓面试题-JAVA篇
- *****************************自己总结的小技巧**********************************
- 24 AIDL案例
- hd 1065 I Think I Need a Houseboat(数学、水)
- Python代理+线程+进程+socket
- HDU 5381The sum of gcd 莫队算法
- 可变参数【Java】
- LA2995- Image Is Everything
- MDK在链接时提示空间不够(No space in execution regions with .ANY selector... )的解决方案总结
- lua封装的位运算
- ORA-00313,ORA-19527
- java基于GUI的定时关机程序
- Retrofit2.0的离线缓存
- Android 优雅的为RecyclerView添加HeaderView和FooterView