hdu5726-GCD-ST表+二分

先用st表处理出所有l-r的GCD值,然后二分求得这些值一共出现了多少次。

  1 #include<bits/stdc++.h>
  2 
  3 #define inf 0x3f3f3f3f
  4 
  5 const int maxn=100000;
  6 
  7 using namespace std;
  8 
  9 typedef pair<int,int> P;
 10 
 11 int l,r;
 12 
 13 int icase;
 14 
 15 int t,n,q;
 16 
 17 int a[maxn+1];
 18 
 19 int dp[maxn+1][20];
 20 
 21 map<int,long long> m;
 22 
 23 int gcd(int a,int b){
 24    return b==0?a:gcd(b,a%b);
 25 }
 26 
 27 void RMQ(){
 28    for(int i=1;i<=n;i++){
 29         dp[i][0]=a[i];
 30    }
 31    for(int j=1;j<20;j++){
 32         for(int i=1;i<=n;i++){
 33                 if(i+((1<<(j-1))-1)<=n)
 34                 dp[i][j]=gcd(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
 35                 //printf("%d\n",dp[i][j]);
 36         }
 37    }
 38 }
 39 
 40 int query(int l,int r){
 41     int k=(int)log2(double(r-l+1));
 42     return gcd(dp[l][k],dp[r-(1<<k)+1][k]);
 43 }
 44 
 45 void Cal(){
 46    for(int i=1;i<=n;i++){
 47         int GCD=a[i],tail=i;
 48         while(tail<=n){
 49              int lb=tail,ub=n,mid=(lb+ub)>>1;
 50              while(ub-lb>1){
 51                 mid=(lb+ub)>>1;
 52                 if(query(i,mid)==GCD) lb=mid;
 53                 else ub=mid;
 54              }
 55              if(query(i,ub)==GCD){
 56                 m[GCD]+=(ub-tail+1);
 57                 tail=ub+1;
 58                 GCD=query(i,tail);
 59              } else if(query(i,mid)==GCD){
 60                 m[GCD]+=(mid-tail+1);
 61                 tail=mid+1;
 62                 GCD=query(i,tail);
 63              }
 64                else{
 65                 m[GCD]+=(lb-tail+1);
 66                 tail=lb+1;
 67                 GCD=query(i,tail);
 68              }
 69         }
 70    }
 71 }
 72 
 73 void solve(){
 74   scanf("%d",&n);
 75   for(int i=1;i<=n;i++){
 76         scanf("%d",&a[i]);
 77   }
 78   RMQ();
 79   Cal();
 80   scanf("%d",&q);
 81   printf("Case #%d:\n",++icase);
 82   while(q--){
 83         scanf("%d%d",&l,&r);
 84         int res=query(l,r);
 85         printf("%d %I64d\n",res,m[res]);
 86   }
 87 }
 88 
 89 void init(){
 90   m.clear();
 91   memset(dp,0,sizeof(dp));
 92 }
 93 
 94 int main()
 95 {
 96     scanf("%d",&t);
 97     while(t--){
 98         init();
 99         solve();
100     }
101     return 0;
102 }

 

posted @ 2016-08-14 10:01  GeniusYang  阅读(256)  评论(0编辑  收藏  举报