Topic links
Give the number of N, define an operation F[l,r] = gcd (al, al+1,.... ar). Then I'll give you M inquiry, each time I ask for L, R. Find out the value of F[l, R] and how many pairs l ', R ' make f[l, r] = F[l ', R '].
The first one is very simple, with a doubling of the thought is possible.
Then the second one, we enumerate each left endpoint I, obviously F[i, J] is only reduced. Then we can find the value J of all that makes F[i, j] fall. Because the GCD at least one-second at a time, and the AI is the maximum of 1e9. So at most only log2 (1E9) such a point. We'll all find out and put it in the map. Specific look at the code
#include <bits/stdc++.h>using namespacestd;#definell Long LongintN;Const intMAXN = 1e5+5;intA[MAXN], f[maxn][ -], Mm[maxn];map<int, ll>MP;intgcdintAintb) { returnB?GCD (b, a%b): A;}voidinitrmq () {mm[0] = -1; for(inti =1; I <= N; i++) {Mm[i]= ((i& (i-1))==0)? mm[i-1]+1: mm[i-1]; } for(intj =1; J < -; J + +) { for(inti =1; i + (1<<J)-1<= N; i++) {F[i][j]= GCD (f[i][j-1], f[i+ (1<< (J-1))][j-1]); } }}intQueryintLintR) { intK = mm[r-l+1]; returnGCD (F[l][k], f[r-(1<<K) +1][k]);}voidPre () { for(inti =1; I <= N; i++) { intg = f[i][0]; intL =I, TMP; while(L <=N) {intL = L, R =N; while(L <=r) {intMID = L+r>>1; if(Query (i, mid) = =g) {tmp=mid; L= mid+1; } Else{R= mid-1; }} Mp[g]+ = (tmp-l+1); L= tmp+1; G= GCD (g, f[l][0]); } }}intMain () {intT, M, L, R; CIN>>T; for(intCasee =1; Casee <= t; casee++) {cin>>N; for(inti =1; I <= N; i++) {scanf ("%d", &A[i]); f[i][0] =A[i]; } mp.clear (); INITRMQ (); Pre (); CIN>>m; printf ("Case #%d:\n", Casee); for(inti =0; I < m; i++) {scanf ("%d%d", &l, &R); intAns =query (l, R); printf ("%d%lld\n", ans, mp[ans]); } }}
HDU 5726 GCD multiplier + two points