首先确定一个右端点 向左做后缀gcd的值是不超过log的 因为gcd必然递减 每次至少除以2
那么可以对每个右端点预处理出来
然后要求区间不同的gcd个数 这里要用到1878: [SDOI2009]HH的项链的技巧
用树状数组离线处理
按右端点的顺序处理询问
令pos[x]等于x这个值出现的最靠右的位置 显然这里是对计算贡献最有利的 然后用树状数组维护下 对于某个位置 有多少个pos的取值是在这里的
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline int read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; else if (c==EOF) return 0;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; return 1;
}
const int N=100005;
int n,m,a[N];
struct abcd{
int l,r,d;
abcd(int l=0,int r=0,int d=0):l(l),r(r),d(d) {}
}G[N][35];
int cnt[N];
inline void Init(){
for (int i=1;i<=n;i++){
for (int j=1;j<=cnt[i-1];j++)
G[i][j]=G[i-1][j],G[i][j].d=__gcd(G[i][j].d,a[i]);
cnt[i]=cnt[i-1]+1;
G[i][cnt[i]]=abcd(i,i,a[i]);
int pnt=0;
for (int j=1;j<=cnt[i];j++){
if (G[i][j].d!=G[i][pnt].d)
G[i][++pnt]=G[i][j];
else
G[i][pnt].r=G[i][j].r;
}
cnt[i]=pnt;
}
}
namespace BIT{
int maxn; ll c[N];
inline void init(int n){ maxn=n; for (int i=1;i<=n;i++) c[i]=0; }
inline void add(int x,int r){ for (int i=x;i<=maxn;i+=i&-i) c[i]+=r; }
inline ll sum(int x) { int ret=0; for (int i=x;i;i-=i&-i) ret+=c[i]; return ret; }
inline ll sum(int l,int r) { return sum(r)-sum(l-1); }
}
struct event{
int l,r,idx;
bool operator < (const event &B) const{ return r<B.r; }
}eve[N];
int tot;
ll ans[N];
int pos[1000005];
int main(){
int T,l,r,Case=0;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
while (read(n)){
read(tot);
for (int i=1;i<=n;i++) read(a[i]);
Init(); BIT::init(n);
for (int i=1;i<=tot;i++) read(eve[i].l),read(eve[i].r),eve[i].idx=i;
sort(eve+1,eve+tot+1);
int pnt=1;
for (int i=1;i<=n;i++){
for (int j=1;j<=cnt[i];j++){
int d=G[i][j].d,r=G[i][j].r;
if (pos[d]) BIT::add(pos[d],-1);
pos[d]=max(r,pos[d]); BIT::add(pos[d],1);
}
while (pnt<=tot && eve[pnt].r==i)
ans[eve[pnt].idx]=BIT::sum(eve[pnt].l,eve[pnt].r),pnt++;
}
for (int i=1;i<=tot;i++)
printf("%I64d\n",ans[i]);
cl(pos);
}
return 0;
}