• 珂朵莉与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
    ",ans[i]);
    	return 0;
    }
    

      

  • 相关阅读:
    求逆序数 noj117
    背包问题 noj106
    士兵杀敌(二)
    Perl 日记模式操作(匹配与替换)
    Symbian中如何调试控制台程序
    Perl 日记references (often used)
    跨平台开发库(Symbian involved)日记1
    无法不想你,CLASSPATH,
    Symbian中不能跨越线程(RThread)使用的对象/组件(RSocket/Memery Heap,etc)
    几种设计模式分类的个人理解
  • 原文地址:https://www.cnblogs.com/wang9897/p/8217053.html
Copyright © 2020-2023  润新知