• Interval GCD


    题目描述

    给定一个长度为N的数列A,以及M条指令 (N≤5*10^5, M<=10^5),每条指令可能是以下两种之一:
    “C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d。
    “Q l r”,表示询问 A[l],A[l+1],…,A[r] 的最大公约数(GCD)

    输入

    第一行两个整数N,M,第二行N个整数Ai,接下来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

    提示

    N,M≤2*10^5,l<=r,数据保证任何时刻序列中的数都是不超过2^62-1的正整数。

    gcd(x,y)=gcd(x,y-x),gcd(x,y,z)=gcd(x,y-x,z-y)……对任意多个整数都成
    将A数列进行查分,线段树维护差分序列的最大公约数,每次询问就是gcd(A[l],query(1,1,n,l+1,r);
    每次修改update(1,1,n,l,d),update(1,1,n,r+1,-d)
    A数组也需要维护,线段树和树状数组都行
    #include<bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=500200;
    char s[10];
    ll a[maxn],b[maxn],B[maxn*4],n,m,A[maxn*4];
    void build (int rt,int l,int r)
    {
        if (l==r)
        {
            B[rt]=b[l];
            return;
        }
        int mid=(l+r)>>1;
        build (rt<<1,l,mid);
        build (rt<<1|1,mid+1,r);
        B[rt]=__gcd(B[rt<<1],B[rt<<1|1]);
    }
    
    void update(int rt,int l,int r,int pos,ll val)
    {
        if (l==r)
        {
            B[rt]+=val;
            return;
        }
        int mid=(l+r)>>1;
        if (pos<=mid)
        {
            update(rt<<1,l,mid,pos,val);
        }
        else
        {
            update(rt<<1|1,mid+1,r,pos,val);
        }
        B[rt]=__gcd(B[rt<<1],B[rt<<1|1]);
    }
    
    ll query(int rt,int l,int r,int L,int R)
    {
        if (L<=l&&r<=R)
        {
            return B[rt];
        }
        int mid=(l+r)>>1;
        if (R<=mid)
        {
            return query(rt<<1,l,mid,L,R);
        }
        else
        {
            if (L>mid)
            {
                return query(rt<<1|1,mid+1,r,L,R);
            }
            else
            {
                return __gcd(query(rt<<1|1,mid+1,r,L,R),query(rt<<1,l,mid,L,R));
            }
        }
    }
    int lowbit(int x)
    {
        return x&-x;
    }
    
    void add(int x,ll val)
    {
        for (int i=x; i<=n; i+=lowbit(i))
        {
            A[i]+=val;
        }
    }
    ll sum(int x)
    {
        ll res=0;
        for (int i=x; i; i-=lowbit(i))
        {
            res+=A[i];
        }
        return res;
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for (int i=1; i<=n; i++)
        {
            scanf("%lld",&a[i]);
            b[i]=a[i]-a[i-1];
            add(i,b[i]);
        }
        build (1,1,n);
        while (m--)
        {
            ll l,r,d;
            scanf("%s",s);
            if (s[0]=='C')
            {
    
                scanf("%lld%lld%lld",&l,&r,&d);
                update(1,1,n,l,d);
                add(l,d);
                add(r+1,-d);
                if (r+1<=n) update(1,1,n,r+1,-d);
            }
            else
            {
                scanf("%lld%lld",&l,&r);
                ll ans=abs(__gcd(sum(l),query(1,1,n,l+1,r)));
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
    
    
    

      

     

      

  • 相关阅读:
    php中常用的字符串函数,大全了
    php写的验证码实现方法
    简单的php做的一个验证码生成方案
    ActiveMQ+SpringMVC+Maven应用示例
    zookeeper简单操作
    zookeeper基本概念及原理
    zookeeper 事务日志与快照日志
    activeMQ安装与测试
    activeMQ "HelloWorld"实现
    JMS基本概念
  • 原文地址:https://www.cnblogs.com/Accpted/p/11311573.html
Copyright © 2020-2023  润新知