2整数におけるGCDは,結合律を満たします.また,多くの言語でGCDの単位元は 0 とされており,整数集合におけるGCDはモノイドであると言えます.従って,セグメント木を用いて,指定区間のGCDは,O(log(N)log(A)) で高速に計算可能です.
また,G(l,r)=gcd(Al,Al+1,Al+2,…Ar) とすると,l を固定したとき,G(l,r) は r について明らかに広義単調減少です.
従って,数列Aの区間における左端 l を固定したとき,G(l,r)≥M を満たす最大の r を r1,G(l,r)>M を満たす最大の r を r2 として,r1−r2 個が G(l,r)=M を満たします.
よって,1 以上 N 以下の l について上の値を二分探索とセグメント木を用いて O(log2(N)×log(A)) で求めることができるため,全体の計算量は O(N×log2(N)log(A)) となりますが,セグメント木上で直接二分探索を行うことで,さらに計算量を O(N×log(N)log(A)) に落とすことができます.
コード例(C++)