码迷,mamicode.com
首页 > 其他好文 > 详细

HDU5726 GCD(二分+ST表)

时间:2016-07-20 09:01:23      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

题目大概说给一个包含n个数的序列,多次询问有多少个区间GCD值等于某个区间的gcd值。

 

任何一个区间不同的GCD个数是log级别的,因为随着右端点向右延伸GCD是单调不增的,而每次递减GCD至少除以2。

考虑固定左端点,最多就nlogn种GCD,可以直接把所有区间GCD值预处理出来,用map存储各种GCD值的个数,查询时直接输出。

具体是这样处理的:枚举左端点,进行若干次二分查找,看当前GCD值最多能延伸到哪儿,进而统计当前GCD值的数量。

而求区间GCD,用ST表,预处理一下,就能在O(1)时间复杂度求出任意区间的gcd了。

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<map>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 int gcd(int a,int b){
 8     while(b){
 9         int t=b;
10         b=a%b;
11         a=t;
12     }
13     return a;
14 }
15 
16 int n,st[17][111111];
17 void init(){
18     for(int i=1; i<17; ++i){
19         for(int j=1; j<=n; ++j){
20             if(j+(1<<i)-1>n) continue;
21             st[i][j]=gcd(st[i-1][j],st[i-1][j+(1<<i-1)]);
22         }
23     }
24 }
25 int logs[111111];
26 int query(int a,int b){
27     int k=logs[b-a+1];
28     return gcd(st[k][a],st[k][b-(1<<k)+1]);
29 }
30 
31 int main(){
32     for(int i=1; i<=100000; ++i){
33         logs[i]=log2(i)+1e-6;
34     }
35     int t;
36     scanf("%d",&t);
37     for(int cse=1; cse<=t; ++cse){
38         scanf("%d",&n);
39         for(int i=1; i<=n; ++i){
40             scanf("%d",&st[0][i]);
41         }
42 
43         init();
44 
45         map<int,long long> rec;
46         for(int i=1; i<=n; ++i){
47             int g=st[0][i],j=i;
48             while(j<=n){
49                 int l=j,r=n;
50                 while(l<r){
51                     int mid=l+r+1>>1;
52                     if(query(i,mid)==g) l=mid;
53                     else r=mid-1;
54                 }
55                 rec[g]+=(l-j+1);
56                 j=l+1;
57                 g=query(i,j);
58 
59             }
60         }
61 
62         printf("Case #%d:\n",cse);
63         int q,a,b;
64         scanf("%d",&q);
65         while(q--){
66             scanf("%d%d",&a,&b);
67             int g=query(a,b);
68             printf("%d %lld\n",g,rec[g]);
69         }
70     }
71     return 0;
72 }

 

HDU5726 GCD(二分+ST表)

标签:

原文地址:http://www.cnblogs.com/WABoss/p/5686994.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!