珂朵莉与GCD
题目描述
给你一个长为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; }