树状数组可解
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100000+100;
const ll mod=1e9+7;
struct Node{
int l,r;
int id;
}node[maxn];
ll ans[maxn];
ll gc[maxn];
ll Ans[maxn];
int pos[maxn];
ll bit[maxn][2];
int n,m;
inline int lowbit(int x){
return x&(-x);
}
inline void Add(int x,ll v){
int tmp=x;
while(x<=n){
bit[x][0]+=v;
bit[x][1]+=tmp*v;
x+=lowbit(x);
}
}
inline ll getSum(int x){
ll sum=0;
int tmp=x;
while(x>0){
sum+=(ll)(tmp+1)*bit[x][0]-bit[x][1];
sum%=mod;
x-=lowbit(x);
}
return sum;
}
inline ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
inline bool cmp(Node a,Node b){
return a.r<b.r;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&ans[i]);
for(int i=1;i<=m;i++) scanf("%d%d",&node[i].l,&node[i].r),node[i].id=i;
sort(node+1,node+1+m,cmp);
int p=1;
int tot=0;
for(int i=1;i<=m;i++){
while(p<=node[i].r){
for(int j=1;j<=tot;j++) gc[j]=gcd(gc[j],ans[p]);
gc[++tot]=ans[p];
pos[tot]=p;
int tmp=0;
for(int j=1;j<=tot;j++) if(gc[j]!=gc[j-1]) {
gc[++tmp]=gc[j];
pos[tmp]=pos[j];
}
tot=tmp;
for(int j=1;j<tot;j++){
Add(pos[j],gc[j]);
Add(pos[j+1],-gc[j]);
}
Add(pos[tot],gc[tot]);
Add(p+1,-gc[tot]);
p++;
}
Ans[node[i].id]=getSum(node[i].r)-getSum(node[i].l-1);
}
for(int i=1;i<=m;i++) printf("%lld\n",Ans[i]%mod);
}