HDU5726
2016-07-27 08:46
387 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726
ST预处理区间GCD,由唯一分解定理可知,任意起点开始的区间GCD值最多只有logN个,所以可以枚举起点,依靠ST二分求gcd变化的位置求出某起点开始的区间GCD为某值的区间个数,然后用map映射。
ST预处理区间GCD,由唯一分解定理可知,任意起点开始的区间GCD值最多只有logN个,所以可以枚举起点,依靠ST二分求gcd变化的位置求出某起点开始的区间GCD为某值的区间个数,然后用map映射。
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<cmath> #include<map> using namespace std; const int N = 1e5+3; int G [31]; int arr ,n; map<int, long long > mp; int gcd(int x,int y) { int t; while (y) { t = x; x = y; y = t%y; } return x; } void init_st() { for (int i=1;i<=n;i++) { G[i][0] = arr[i]; } for (int j=1;j<=30;j++) { for (int i=1;i<=n;i++) { if (i+(1<<j)-1 <= n) { G[i][j] = gcd(G[i][j-1],G[i+(1<<(j-1) ) ][j-1] ); } } } } int getgcd(int l,int r) { int k = (int) (log(r-l+1) / log(2.0) ); int t1 = G[l][k]; int t2 = G[r-(1<<k)+1][k]; return gcd(t1,t2); } int main() { int T; scanf("%d",&T); for (int cnt=1;cnt<=T;cnt++) { mp.clear(); scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&arr[i]); } init_st(); for (int i=1;i<=n;i++) { int g = arr[i],j = i; while (j<=n) { int l = j , r = n; while (l<r) { int mid = l+r+1>>1; if (getgcd(i,mid)==g) l = mid; else r = mid - 1; } mp[g] += (l - j + 1); j = l + 1; g = getgcd(i,j); } } int k; scanf("%d",&k); printf("Case #%d:\n",cnt); while (k--) { int s,e; scanf("%d %d",&s,&e); int t = getgcd(s,e); printf("%d %I64d\n",t,mp[t]); } } return 0; }
相关文章推荐
- 2015阿里实习招聘笔试题-自己尝试做的答案
- ubuntu下Android4.4 CTS搭建(一)
- javascript获取网页各种高宽及位置的方法总结
- eclipse 创建springmvc4_hibernate5_maven web工程
- JSONP
- 网页编码问题
- redis 学习指南
- JavaScrip使用语法规范
- 10个值得深思的PHP面试问题
- POJ 3278 Catch That Cow(BFS)
- Rookey.Frame之实体FluentValidation验证
- CodeForces 540C Ice Cave
- 第一次接触神奇的Bootstrap表单
- linux部署web项目到tomcat下(图文详解)
- C++ map的基本操作和使用
- Javascript 数组
- 纠正对Fragment Transaction BackStack的误解
- Catch That Cow
- c#基础入门(3)——异常、三元表达式、转义符、类型转换
- su - postgres时,显示为bash-4.2$如何解决