珂朵莉与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;
}

  

posted @ 2018-01-07 00:51  wang9897  阅读(416)  评论(0编辑  收藏  举报