The title probably says to a sequence containing n numbers, asking several times how many interval gcd values are equal to the GCD values of an interval.
The number of GCD for any one interval is the log level, because the right endpoint extends gcd to the right, and each decrement gcd at least divided by 2.
Consider fixed left endpoint, up to Nlogn species GCD, can directly be all the interval GCD value preprocessing, with map to store the number of GCD values, query directly output.
This is done in this way: Enumerate the left endpoint, perform a number of sub-binary lookups, see where the current GCD value can reach, and then count the current GCD value.
And the interval gcd, with St table, pretreatment, can be in O (1) time complexity to find out any interval of GCD.
1#include <cstdio>2#include <cmath>3#include <map>4#include <algorithm>5 using namespacestd;6 7 intgcdintAintb) {8 while(b) {9 intt=b;Tenb=a%b; OneA=T; A } - returnA; - } the - intn,st[ -][111111]; - voidinit () { - for(intI=1; i< -; ++i) { + for(intj=1; j<=n; ++j) { - if(J+ (1<<i)-1>n)Continue; +ST[I][J]=GCD (st[i-1][j],st[i-1][j+ (1<<i-1)]); A } at } - } - intlogs[111111]; - intQueryintAintb) { - intk=logs[b-a+1]; - returnGCD (st[k][a],st[k][b-(1<<K) +1]); in } - to intMain () { + for(intI=1; i<=100000; ++i) { -LOGS[I]=LOG2 (i) +1e-6; the } * intT; $scanf"%d",&t);Panax Notoginseng for(intCse=1; cse<=t; ++CSE) { -scanf"%d",&n); the for(intI=1; i<=n; ++i) { +scanf"%d", &st[0][i]); A } the + init (); - $map<int,Long Long>Rec; $ for(intI=1; i<=n; ++i) { - intg=st[0][i],j=i; - while(j<=N) { the intL=j,r=N; - while(l<S) {Wuyi intmid=l+r+1>>1; the if(Query (I,mid) ==g) l=mid; - Elser=mid-1; Wu } -rec[g]+= (l-j+1); Aboutj=l+1; $g=query (i,j); - - } - } A +printf"Case #%d:\n", CSE); the intq,a,b; -scanf"%d",&q); $ while(q--){ thescanf"%d%d",&a,&b); the intg=query (A, b); theprintf"%d%lld\n", G,rec[g]); the } - } in return 0; the}
HDU5726 GCD (two-+st table)