题目描述
给你一个长为n的序列a
m次查询
每次查询一个区间的所有子区间的gcd的和mod1e9+7的结果
输入描述:
第一行两个数n,m
之后一行n个数表示a
之后m行每行两个数l,r表示查询的区间
输出描述:
对于每个询问,输出一行一个数表示答案
#include <bits/stdc++.h>
#define N 100005
#define lth 1000000007
#define ll long long
using namespace std;
int a[N];
int _gcd(int x,int y){
if(y==0) return x;
else return(_gcd(y,x%y));
}
int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
vector<pair<int,int> >vec[N];
typedef struct node{
int l,r;ll v;ll flag;
}node;
node d[N<<2];
ll ans[N];
void built(int root,int l,int r){
if(l==r){
d[root].l=l;d[root].r=r;d[root].v=0;d[root].flag=0;
return ;
}
int mid=(l+r)>>1;
built(root<<1,l,mid);
built(root<<1|1,mid+1,r);
d[root].l=d[root<<1].l;d[root].r=d[root<<1|1].r;d[root].v=0;d[root].flag=0;
}
void push(int root){
if(d[root].flag!=0){
d[root<<1].flag+=d[root].flag;d[root<<1|1].flag+=d[root].flag;
d[root<<1].v=(1ll*(d[root<<1].r-d[root<<1].l+1)*d[root].flag+d[root<<1].v)%lth;
d[root<<1|1].v=(1ll*(d[root<<1|1].r-d[root<<1|1].l+1)*d[root].flag+d[root<<1|1].v)%lth;
d[root].flag=0;
}
}
void update(int root,int l,int r,int t){
if(l<=d[root].l&&d[root].r<=r){
d[root].v=(1ll*t*(d[root].r-d[root].l+1)+d[root].v)%lth;d[root].flag+=t;
return ;
}
int mid=(d[root].l+d[root].r)>>1;
push(root);
if(l<=mid) update(root<<1,l,r,t);
if(r>mid) update(root<<1|1,l,r,t);
d[root].v=(d[root<<1].v+d[root<<1|1].v)%lth;
}
ll ans1;
void querty(int root,int l,int r){
if(l<=d[root].l&&d[root].r<=r){
ans1=(ans1+d[root].v)%lth;
return ;
}
int mid=(d[root].l+d[root].r)>>1;
push(root);
if(l<=mid) querty(root<<1,l,r);
if(r>mid) querty(root<<1|1,l,r);
d[root].v=(d[root<<1].v+d[root<<1|1].v)%lth;
}
typedef struct lr{
int l,r,biao;
friend bool operator <(lr aa,lr bb){
return aa.r<bb.r;
}
}lr;
lr bi[N];
int main(){
int n,q;
n=read();q=read();
for(int i=1;i<=n;i++) a[i]=read();
built(1,1,n);
int id,vul,l,r;
for(int i=1;i<=n;i++){
id=i;vul=a[i];
for(int j=0;j<vec[i-1].size();j++){
int res=_gcd(vul,vec[i-1][j].second);
if(vul!=res){
vec[i].push_back(make_pair(id,vul));
vul=res;id=vec[i-1][j].first;
}
}
vec[i].push_back(make_pair(id,vul));
}
for(int i=1;i<=q;i++){
l=read();r=read();bi[i].l=l;bi[i].r=r;bi[i].biao=i;
}
sort(bi+1,bi+1+q);r=1;
for(int i=1;i<=q;i++){
while(r<=bi[i].r){
for(int j=0;j<vec[r].size()-1;j++){
update(1,vec[r][j+1].first+1,vec[r][j].first,vec[r][j].second);
}
update(1,1,vec[r][vec[r].size()-1].first,vec[r][vec[r].size()-1].second);
r++;
}
ans1=0;
querty(1,bi[i].l,bi[i].r);
ans[bi[i].biao]=ans1;
}
for(int i=1;i<=q;i++) printf("%lld\n",ans[i]);
return 0;
}