zoukankan      html  css  js  c++  java
  • AcWing 246. 区间最大公约数

    • 差分
    • (gcd)

    证明:(gcd(a_1,a_2,a_3,...,a_n)=gcd(a_1,a_2-a_1,a_3-a_2,...,a_n-a_{n-1})).
    为方便描述 令 (c_1=a_1,c_i=a_i-a_{i-1},i>1).
    设其最大公约数为 (d) , 则 (d|a_1,d|a_2,..., --> d|(a_2-a_1)...)
    左边(=d);
    右边(=d imes gcd(c_1/d,c_2/d,...))
    引理:(gcd(c_1/d,c_2/d,...)=1)
    反证法:若 (gcd(c_1/d,c_2/d,...)=k,k>1).

    • (a_1/d=c_1/d=x imes k)
    • (c_2/d=(a_2-a_1)/d=y imes k)
    • (a_2/d=(a_1+c_2)/d=x imes k + y imes k=(x+y) imes k),(k|a_2)
    • ...
    • 同理得 (k|(a_i/d),i in [1,n])

    (gcd(a_1,a_2,a_3,...,a_n)=d imes k).
    与题设不符,舍去。

    所以 (gcd(c_1/d,c_2/d,...)=1)
    右边$=d imes gcd(c_1/d,c_2/d,...)= d = $ 左边。

    即证。

    Code:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    
    using namespace std;
    typedef long long LL;
    const int N=5e5+5;
    
    LL a[N],c[N];
    int n,m;
    
    LL gcd(LL a,LL b) 
    {
        if(b==0) return a;
        else return gcd(b,a%b);
    }
    #define lc (now<<1)
    #define rc (now<<1|1)
    LL sum[4*N],d[4*N];
    void Update(int now,int pos,LL key,int l,int r)
    {
        if(l==r&&l==pos) {
            sum[now]+=key;
            d[now]+=key;
            return;
        }
        int mid=(l+r)>>1;
        if(pos<=mid) Update(lc,pos,key,l,mid);
        else Update(rc,pos,key,mid+1,r);
    
        sum[now]=sum[lc]+sum[rc];
        d[now]=gcd(d[lc],d[rc]);
    }
    
    LL QuerySum(int now,int pos,int l,int r)
    {
        if(r<=pos) return sum[now];
        int mid=(l+r)>>1;
        LL res=QuerySum(lc,pos,l,mid);
        if(pos>=mid+1) res+=QuerySum(rc,pos,mid+1,r);
        return res;
    }
    
    LL QueryGcd(int now,int x,int y,int l,int r)
    {
        if(x<=l&&r<=y) return d[now];
        int mid=(l+r)>>1;
        LL res=0;
        if(x<=mid) res=gcd(res,QueryGcd(lc,x,y,l,mid));
        if(y>=mid+1) res=gcd(res,QueryGcd(rc,x,y,mid+1,r));
        return res;
    }
    
    
    int main()
    {
        int i;
        int x,y;
        LL z;
        char opt;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++) {
            scanf("%lld",&a[i]);
            c[i]=a[i]-a[i-1];
            Update(1,i,c[i],1,n);
        }
        while(m--) {
            for(opt=getchar();opt!='C'&&opt!='Q';opt=getchar());
            scanf("%d%d",&x,&y);
            if(opt=='Q') printf("%lld
    ",abs(gcd(QueryGcd(1,x+1,y,1,n),QuerySum(1,x,1,n))));
            else {
                scanf("%lld",&z);
                Update(1,x,z,1,n);
                if(y+1<=n) Update(1,y+1,-z,1,n);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    [转]relative、absolute和float
    CSS 布局属性(display,float,clear,visibility,overflow,overflow-x,overflow-y)
    CSS 块状元素和内联元素
    CSS定位
    CSS实例
    jQuery简单实例
    [转]几种常见SQL分页方式
    MyBatis Mapper XML 文件
    MyBatis XML 映射配置文件
    MyBatis 入门
  • 原文地址:https://www.cnblogs.com/cjl-world/p/14054158.html
Copyright © 2011-2022 走看看