hdu 5726 GCD
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define cl(a,b) memset(a,b,sizeof(a)) 4 #define LL long long 5 #define pb push_back 6 #define gcd __gcd 7 8 const int maxn = 1e5+200; 9 const int inf = 1 << 23; 10 11 int n;LL a[maxn]; 12 LL node[maxn*4]; 13 14 void push_up(int rt){ 15 node[rt] = gcd(node[rt<<1],node[rt<<1|1]); 16 } 17 18 void build(int rt,int l,int r){ 19 if(l==r){ 20 node[rt]=a[l]; 21 return ; 22 } 23 int mid = l+r>>1; 24 build(rt<<1, l, mid); 25 build(rt<<1|1, mid+1, r); 26 push_up(rt); 27 } 28 29 LL query(int rt,int l,int r,int x,int y){ 30 //printf("rt = %d, l = %d, r = %d, x = %d,y = %d\n",rt,l,r,x,y); 31 if(x<=l&&y>=r){ 32 return node[rt]; 33 } 34 int mid = l+r>>1; 35 LL lson=0 ,rson=0; 36 37 if(x<=mid) lson = query(rt<<1,l,mid,x,y); 38 if(y>mid) rson = query(rt<<1|1,mid+1,r,x,y); 39 if(lson==0)return rson; 40 if(rson==0)return lson; 41 return gcd(lson,rson); 42 } 43 44 map<LL,LL> f[maxn];//f[i]记录下第a[i]形成的gcd的集合 45 map<LL,LL> ans; 46 47 int main(){ 48 int T;scanf("%d",&T); 49 int cas = 1; 50 while(T--){ 51 52 scanf("%d",&n); 53 for(int i=1;i<=n;i++){ 54 scanf("%d",&a[i]); 55 } 56 printf("Case #%d:\n",cas++); 57 58 build(1,1,n); 59 ans.clear(); 60 for(int i=0;i<=n;i++)f[i].clear(); 61 62 ans[a[1]]=1;f[1][a[1]]=1; 63 for(int i=2;i<=n;i++){ 64 ans[a[i]]++;f[i][a[i]]+=1; 65 for(map<LL,LL>::iterator it = f[i-1].begin();it!=f[i-1].end();it++){ 66 LL tmp = gcd(a[i],it->first); 67 f[i][tmp]+=it->second; 68 ans[tmp]+=it->second; 69 } 70 } 71 72 int q;scanf("%d",&q); 73 while(q--){ 74 int x,y;scanf("%d%d",&x,&y); 75 LL _gcd = query(1,1,n,x,y); 76 printf("%lld %lld\n",_gcd,ans[_gcd]); 77 } 78 } 79 return 0; 80 }