1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
   | #include<stdio.h> #include<string.h> #include<map> using namespace std; const int N=100010; int a[N]; int tree[N<<2]; map<int,long long> mp; int gcd(int a,int b) {     return b==0?a:gcd(b,a%b); } void pushUp(int node) {     tree[node]=gcd(tree[node<<1],tree[node<<1|1]); } void build(int l,int r,int node) {     if(l==r){         tree[node]=a[l];         return;     }     int mid=(l+r)>>1;     build(l,mid,node<<1);     build(mid+1,r,node<<1|1);     pushUp(node); } int query(int l,int r,int node,int ql,int qr) {     if(ql<=l&&r<=qr){         return tree[node];     }     int mid=(l+r)>>1;     int ans=0;     if(mid>=ql)         ans=gcd(ans,query(l,mid,node<<1,ql,qr));     if(mid<qr)         ans=gcd(ans,query(mid+1,r,node<<1|1,ql,qr));     return ans; }
 
  {     while(l<=r){         int mid=(l+r)>>1;         int tmp=query(1,n,1,l,mid);         if(gcd(now,tmp)<g)             r=mid-1;         else{             now=gcd(now,tmp);             l=mid+1;         }     }     return r+1; }*/ int binSearch(int l,int r,int node,int ql,int qr,int g,int &now) {     if(ql<=l&&r<=qr){         if(gcd(now,tree[node])<g){             if(l==r)                 return l;             int mid=(l+r)>>1;             int left=0;             left=binSearch(l,mid,node<<1,ql,qr,g,now);             if(left!=0)                 return left;             return binSearch(mid+1,r,node<<1|1,ql,qr,g,now);         }         else{             now=gcd(now,tree[node]);             return 0;         }     }     int mid=(l+r)>>1;     int left=0,right=0;     if(ql<=mid){         left=binSearch(l,mid,node<<1,ql,qr,g,now);         if(left!=0)             return left;     }     if(mid<qr)         right=binSearch(mid+1,r,node<<1|1,ql,qr,g,now);     return right; } int main() {     int T;     scanf("%d",&T);     for(int k=1;k<=T;k++){         printf("Case #%d:\n",k);         int n;         scanf("%d",&n);         mp.clear();         for(int i=1;i<=n;i++)             scanf("%d",&a[i]);         build(1,n,1);         for(int i=1;i<=n;i++){             int g=a[i];             int left=i;             int G=query(1,n,1,i,n);             while(left<=n){                 if(G==g){                     mp[G]+=n-left+1;                     break;                 }                                  int now=a[i];                 int pos=binSearch(1,n,1,i,n,g,now);                 mp[g]+=pos-left;                 left=pos;                 g=gcd(g,a[left]);             }         }         int q;         scanf("%d",&q);         int l,r;         while(q--){             scanf("%d%d",&l,&r);             int g=query(1,n,1,l,r);             printf("%d %lld\n",g,mp[g]);         }     }     return 0; }
   |