[2016ACM多校] HDU5726 st表 离线
来源:互联网 发布:金淘店管软件多少钱 编辑:程序博客网 时间:2024/05/21 15:00
题意
给n个数{a[i]},q个询问(l,r),与[l,r]最大公约数相同的区间有多少个。
思路
首先是查询最大公约数,然后统计相同的区间。查询可以用各种结构,既然只用查询那就用st简单高效,主要考虑统计。指定开头s,那么从s开始的区间,随着结尾t的减小,gcd减小,gcd种类不超过log(a[s])个,可以二分每种gcd结束的位置,然后累加。这样全统计时间复杂度为O(n*logn*logn),鉴于gcd的log很小不会超时。内存方面,可以用一个map记录询问了哪些gcd,然后只累加相应的结果,其他的就不管了。
AC代码 C++
#include <stdio.h>#include <algorithm>#include <map>#define MAXN 100005using namespace std;int a[MAXN];int st[MAXN][20];int ans[MAXN];inline int rmq(int l, int r){ int limit=0; while(1 << limit+1 <= r - l + 1) limit++; return __gcd(st[l][limit], st[r-(1<<limit)+1][limit]);}int main(){ int T, t, n, q, i, j, k, l, r, limit; scanf("%d", &T); for(t=1; t<=T; t++) { scanf("%d", &n); for(i=1; i<=n; i++) scanf("%d", a+i); for(i=1, limit=0; i<=n; i++) st[i][0] = a[i]; while(1 << limit <= n) limit++; for(i=1; i<limit; i++) for(j=1; j+(1<<i)<n+2; j++) st[j][i] = __gcd(st[j][i-1], st[j+(1<<i-1)][i-1]); map<int, long long> sum; scanf("%d", &q); for(i=0; i<q; i++) { scanf("%d%d", &l, &r); sum[ans[i] = rmq(l, r)] = 0; } for(i=1; i<=n; i++) { j = i; while(true) { limit = rmq(i, j); l = j; r = n + 1; while(l < r) { k = l + r >> 1; if(rmq(i, k) != limit) r = k; else l = k + 1; } if(sum.find(limit) != sum.end()) sum[limit] += (long long)r - j; if(r > n) break; else j = r; } } printf("Case #%d:\n", t); for(i=0; i<q; i++) printf("%d %I64d\n", ans[i], sum[ans[i]]); } return 0;}
0 0
- [2016ACM多校] HDU5726 st表 离线
- hdu5726 GCD ST表+离线
- hdu5726 GCD st表 + 二分
- hdu5726 GCD+ST表 by:lethalboy
- RMQ -ST ——hdu5726 GCD
- hdu5726 GCD 多校1
- HDU5726
- hdu5726
- HDU5726
- hdu5726
- hdu5726
- HDU2586 RMQ+ST && 离线算法
- hdu5726 多校1 GCD【rmq+二分】
- ST表
- st表
- st表
- st表
- ST表
- 支付宝支付的流程
- [知了开发]“知了”APP整体设计
- APP开发实战106-缓存实现
- 时钟系统
- AIX常用命令汇总
- [2016ACM多校] HDU5726 st表 离线
- c++ 关于char *的类库函数
- 剑指offer——字符流中第一个不重复的字符
- 浏览器地址栏运行HTML代码(谷歌)
- AIX常用文章集锦
- Android事件分发机制
- log4j2配置文件详解
- Hadoop环境搭建(二)
- 谈谈对布局文件、自定义控件、Fragment、Activity的认识