zoukankan      html  css  js  c++  java
  • GCD

    GCD:

    题目描述:

    给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:
    1、“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。
    2、“Q l r”,表示询问 A[l],A[l+1],…,A[r] 的最大公约数(GCD)。
    对于每个询问,输出一个整数表示答案。

    输入:

    第一行两个整数N,M。
    第二行N个整数A[i]。
    接下来M行表示M条指令,每条指令的格式如题目描述所示。

    输出:

    对于每个询问,输出一个整数表示答案。 每个答案占一行。

    样例输入:

    5 5
    1 3 5 7 9
    Q 1 5
    C 1 5 1
    Q 1 5
    C 3 3 6
    Q 2 4
    

    样例输出:

    1
    2
    4
    

    题解:

    对于(gcd(a , b) = gcd(b , a-b)) 可知(gcd(a1,a2,a3,a4,.......an) = gcd(a1,a2 - a1,a3 - a2,a4 - a3,.......an - an-1)) 所以对于l与r之间的数同时做加减之后该区间的gcd变为gcd(al+x,gcd(l+1,r)),由此可以将区间值更新转化为单点值更新,由ai - a(i-1) 可以想到用差分来跑线段树。线段树维护差分数组的区间gcd值,用树状数组和单点更新来记录变化,比如,如果对 l 到 r 区间加上 x ,那么只需更新树状数组,l起始处加x,r+1起始处 -x ,当我们执行q操作时,直接输出(gcd(al+x,ask_gcd(l+1,r)))

    /**********************************************************
    * @Author: 			   Maple
    * @Date:   			   2020-02-21 09:37:51
    * @Last Modified by:   Maple
    * @Last Modified time: 2020-02-21 16:05:24
    * @Remark: 
    **********************************************************/
    #include <bits/stdc++.h>
    #define lowbit(x) (x&(-x))
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define INF 0x3f3f3f3f
    #define Abs(x) (x>=0?x:(-x))
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll , ll> pll;
    
    const int maxn=500050;
    ll n,m,a[maxn],tree[maxn<<2],dff[maxn],tt[maxn];
    
    ll gcd(ll a,ll b){
    	return b == 0?a:gcd(b,a % b);
    }
    
    void build_tree(int ad,int l,int r){
    	if(l==r){
    		tree[ad]=dff[l];
    		return;
    	}
    	int mid=(l+r)>>1;
    	build_tree(ad<<1,l,mid);
    	build_tree(ad<<1|1,mid+1,r);
    	tree[ad]=gcd(tree[ad<<1],tree[ad<<1|1]);
    	return;
    }
    
    ll get_sum(int ad,int l,int r,int x,int y){
    	if(l>=x&&r<=y){
    		return tree[ad];
    	}
    	int mid=(l+r)>>1;
    	ll ans=0;
    	if(x<=mid)
    		ans=gcd(ans,get_sum(ad<<1,l,mid,x,y));
    	if(y>mid)
    		ans=gcd(ans,get_sum(ad<<1|1,mid+1,r,x,y));
    	return Abs(ans);
    }
    
    void change(int ad,int l,int r,int x,ll y){
    	if(l==r){
    		tree[ad]+=y;
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(x<=mid)
    		change(ad<<1,l,mid,x,y);
    	else
    		change(ad<<1|1,mid+1,r,x,y);
    	tree[ad]=gcd(tree[ad<<1],tree[ad<<1|1]);
    	return;
    }
    
    void update(int x,ll y){
    	while(x<=n){
    		tt[x]+=y;
    		x+=lowbit(x);
    	}
    	return;
    }
    
    ll ask(int x){
    	ll ans=0;
    	while(x>0){
    		ans+=tt[x];
    		x-=lowbit(x);
    	}
    	return ans;
    }
    
    int main()
    {
    	#ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	#endif
    	cin >> n >> m;
    	for(int i = 1;i <= n;i++){
    		scanf("%lld",a+i);
    	}
    	for(int i = 1;i <= n;i++){
    		dff[i] = a[i] - a[i-1];
    	}
    	build_tree(1,1,n);
    	while(m--){
    		char s[5];
    		int l,r;
    		scanf("%s%d%d",s,&l,&r);
    		if(s[0]=='C'){
    			ll d;
    			scanf("%lld",&d);
    			change(1,1,n,l,d);
    			update(l,d);
    			if(r+1<=n){
    				change(1,1,n,r+1,-d);
    				update(r+1,-d);
    			}
    		}
    		else{
    			printf("%lld
    ",gcd(a[l]+ask(l),get_sum(1,1,n,l+1,r)));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    jQuery对象初始化的多种传参数形式
    Ajax核心技术之XMLHttpRequest
    【转载】神奇的css属性pointer-events
    JavaScript学习笔记——错误处理
    jquery validate的漂亮css样式验证
    JavaScript Math和Number对象研究
    《JavaScript语言精粹》笔记
    HTML5版的String Avoider小游戏
    IE11 F12工具报错
    css之图片羽化处理
  • 原文地址:https://www.cnblogs.com/LeafLove/p/12341847.html
Copyright © 2011-2022 走看看