For the first question: no modified query interval GCD, you can use the idea of rmq multiplication.
Second question: Can be preprocessed. Violent enumeration left endpoint L. GCD from left to right are decremented, and there must be some segments that are the same value, with a value of up to only log (1000, 000, 000), so you can determine the range of each paragraph in two minutes. Then you can use map to count it.
#include <cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<map>#include<Set>#include<queue>#include<stack>#include<iostream>using namespaceStd;typedefLong LongLL;Const intmaxn=100000+Ten;intt,n,a[maxn],dp[maxn][ -];map<int,ll>M;intgcdintAintb) {if(b==0)returnAreturnGCD (b,a%b); }voidRmq_init () { for(intI=0; i<n;i++) dp[i][0]=A[i]; for(intj=1;(1<<J) <=n;j++) for(intI=0; i+ (1<<J)-1<n;i++) Dp[i][j]=GCD (dp[i][j-1],dp[i+ (1<< (J-1))][j-1]);}intRMQ (intLintR) { intk=0; while((1<< (k +1)) <=r-l+1) k++; returnGCD (dp[l][k],dp[r-(1<<K) +1][k]);}voidPre () {m.clear (); for(intI=0; i<n;i++) { intp=i; while(p<N) {intll=p,rr=n-1, POS; while(ll<=RR) { intMid= (LL+RR)/2; if(RMQ (I,mid) <rmq (i,p)) rr=mid-1; ElsePos=mid,ll=mid+1; } M[RMQ (i,p)]=M[RMQ (i,p)]+ (LL) (pos-p+1); P=pos+1; } }}intMain () {scanf ("%d", &t);intcas=0; while(t--) {scanf ("%d",&N); for(intI=0; i<n;i++) scanf ("%d",&A[i]); Rmq_init (); Pre (); intQ scanf"%d",&q); printf ("Case #%d:\n",++CAs); for(intI=1; i<=q;i++) { intL,r; scanf"%d%d", &l,&r); L--, r--; printf ("%d%lld\n", RMQ (l,r), M[RMQ (L,r)]); } } return 0;}
HDU 5726 GCD