hdu 5726 GCD (二分+ST表)★
2016-08-06 10:10
387 查看
题目大概说给一个包含n个数的序列,多次询问有多少个区间GCD值等于某个区间的gcd值。
任何一个区间不同的GCD个数是log级别的,因为随着右端点向右延伸GCD是单调不增的,而每次递减GCD至少除以2。
考虑固定左端点,最多就nlogn种GCD,可以直接把所有区间GCD值预处理出来,用map存储各种GCD值的个数,查询时直接输出。
具体是这样处理的:枚举左端点,进行若干次二分查找,看当前GCD值最多能延伸到哪儿,进而统计当前GCD值的数量。
而求区间GCD,用ST表,预处理一下,就能在O(1)时间复杂度求出任意区间的gcd了。
任何一个区间不同的GCD个数是log级别的,因为随着右端点向右延伸GCD是单调不增的,而每次递减GCD至少除以2。
考虑固定左端点,最多就nlogn种GCD,可以直接把所有区间GCD值预处理出来,用map存储各种GCD值的个数,查询时直接输出。
具体是这样处理的:枚举左端点,进行若干次二分查找,看当前GCD值最多能延伸到哪儿,进而统计当前GCD值的数量。
而求区间GCD,用ST表,预处理一下,就能在O(1)时间复杂度求出任意区间的gcd了。
#include <set> #include <map> #include <stack> #include <queue> #include <deque> #include <cmath> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define L(i) i<<1 #define R(i) i<<1|1 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-9 #define maxn 10010 #define MOD 1000000007 int gcd(int a,int b) { while(b) { int t = b; b = a % b; a = t; } return a; } int n,st[110010][17]; void init() { for(int j = 1; j < 17; j++) for(int i = n; i >= 1; i--) { if(i+(1<<j)-1 > n) continue; st[i][j] = gcd(st[i][j-1],st[i+(1<<j-1)][j-1]); } } int logs[100100]; int query(int a,int b) { int k = logs[b-a+1]; return gcd(st[a][k],st[b-(1<<k)+1][k]); } int main() { int t,C = 1; scanf("%d",&t); for(int i = 1; i < 100100; i++) logs[i] = log2(i) + 1e-6; while(t--) { scanf("%d",&n); for(int i = 1; i <= n; i++) scanf("%d",&st[i][0]); init(); map<int,long long> ret; for(int i = 1; i <= n; i++) { int g = st[i][0]; int j = i; while(j <= n) { int l = j, r = n; while(l < r) { int mid = l + r + 1 >> 1; if(query(i,mid) == g) l = mid; else r = mid - 1; } ret[g] += (l - j + 1); j = l + 1; g = query(i,j); } } printf("Case #%d:\n",C++); int q,a,b; scanf("%d",&q); while(q--) { scanf("%d%d",&a,&b); int g = query(a,b); printf("%d %lld\n",g,ret[g]); } } return 0; }
相关文章推荐
- HDU 5726 GCD(RMQ 查询 + 二分)
- GCD HDU - 5726 (ST算法+二分)
- HDU 5726 GCD (rmq+二分 or 线段树 维护区间gcd)
- hdu 5726 GCD rmq 二分
- HDOJ 5726 GCD 二分+ST表
- HDU 5726 GCD (DP+二分)
- hdu-5726 GCD 思维||二分
- HDU 5726-D-GCD- RMQ+二分
- HDU 5726 GCD (RMQ + 二分)
- HDU 5726 GCD(Sparse-Table+二分)
- hdu 5726 区间gcd RMQ+二分 || 暴力枚举
- HDU 5726 GCD(RMQ+二分,详解,ST算法)
- HDU 5726 GCD(rmq+二分)
- HDU 5726 GCD [ST表+暴力二分]【数据结构|杂类】
- HDU 5726 GCD(RMQ+二分)
- HDU 5726 GCD(ST+二分)
- hdu 5726 GCD RMQ+二分枚举
- HDU 5726 GCD(RMQ + 二分)
- HDU 5726 GCD(RMQ+二分)(线段树也可)
- Hdu 5726 GCD【思维+二分+区间Gcd】好题!