• 牛客小白月赛16 H小阳的贝壳 (线段树+差分数组)


    链接:https://ac.nowcoder.com/acm/contest/949/H
    来源:牛客网

    题目描述

    小阳手中一共有 n 个贝壳,每个贝壳都有颜色,且初始第 i 个贝壳的颜色为 colicoli 。现在小阳有 3 种操作:

    1 l r x:给 [l,r][l,r] 区间里所有贝壳的颜色值加上 xx 。

    2 l r:询问 [l,r][l,r] 区间里所有相邻贝壳 颜色值的差(取绝对值) 的最大值(若 l=rl=r 输出 0)。

    3 l r :询问 [l,r][l,r] 区间里所有贝壳颜色值的最大公约数。

    输入描述:

    第一行输入两个正整数 n,mn,m,分别表示贝壳个数和操作个数。
    第二行输入 nn 个数 colicoli,表示每个贝壳的初始颜色。
    第三到第 m+2m+2 行,每行第一个数为 optopt,表示操作编号。接下来的输入的变量与操作编号对应。

    输出描述:

    共 m 行,对于每个询问(操作 2 和操作 3)输出对应的结果。
    示例1

    输入

    5 6
    2 2 3 3 3
    1 2 3 3
    2 2 4
    3 3 5
    1 1 4 2
    3 2 3
    2 3 5

    输出

    3
    3
    1
    3

    备注:

    1n,m105,1coli,x103,1opt3,1lrn


    解题思路:自己没写出来,看了题解感觉很有道理。根据gcd的性质有gcd(a,b)=gcd(a,b-a),有gcd(a,b,c)=gcd(a,b-a,c-b),可以联想到在线段树中建立一个差分数组,用线段树来维护区间和与区间gcd ,对于操作一直接进行单点更新l和r+1即可,对于操作二,我们可以用线段树维护差分数组的差的最大值和最小值,比较一下它们绝对值大小取绝对值大的那就就可以了,对于操作三,可以先查找出前l项的和即为第l个数的值,然后再和区间[l+1,r]上的gcd再求一下gcd就可以了。

    代码:
    //gcd(x,y,z)=gcd(x,y-x,z-y)=gcd(a,gcd(y-x,z-y))
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+7;
    int n,m,a[maxn*4],Sum[maxn*4],Min[maxn*4],Max[maxn*4],Gcd[maxn*4];
    int gcd(int a,int b){return b?gcd(b,a%b):a;}
    void pushup(int rt){
        Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];
        Min[rt]=min(Min[rt<<1],Min[rt<<1|1]);
        Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
        Gcd[rt]=gcd(Gcd[rt<<1],Gcd[rt<<1|1]);
    }
    void build(int l,int r,int rt){
        if(l==r){
            Sum[rt]=Min[rt]=Max[rt]=Gcd[rt]=a[l]-a[l-1];
            return;
        }
        int mid=l+r>>1;
        build(l,mid,rt<<1);
        build(mid+1,r,rt<<1|1);
        pushup(rt);
    }
    void update(int pos,int val,int l,int r,int rt){
        if(l==r){
            Sum[rt]+=val;
            Min[rt]+=val;
            Max[rt]+=val;
            Gcd[rt]+=val;
            return;
        }
        int mid=l+r>>1;
        if(mid>=pos) update(pos,val,l,mid,rt<<1);
        if(mid<pos) update(pos,val,mid+1,r,rt<<1|1);
        pushup(rt);
    }
    int query_sum(int L,int R,int l,int r,int rt){
        if(L>R) return 0;
        if(L<=l&&R>=r){
            return Sum[rt];
        }
        int mid=l+r>>1,res=0;
        if(mid>=L) res+=query_sum(L,R,l,mid,rt<<1);
        if(mid<R) res+=query_sum(L,R,mid+1,r,rt<<1|1);
        return res;
    }
    int query_min(int L,int R,int l,int r,int rt){
        if(L>R) return 0;
        if(L<=l&&R>=r){
            return Min[rt];
        }
        int mid=l+r>>1,res=2e9+7;
        if(mid>=L) res=min(res,query_min(L,R,l,mid,rt<<1));
        if(mid<R) res=min(res,query_min(L,R,mid+1,r,rt<<1|1));
        return res;
    }
    int query_max(int L,int R,int l,int r,int rt){
        if(L>R) return 0;
        if(L<=l&&R>=r){
            return Max[rt];
        }
        int mid=l+r>>1,res=-(2e9+7);
        if(mid>=L) res=max(res,query_max(L,R,l,mid,rt<<1));
        if(mid<R) res=max(res,query_max(L,R,mid+1,r,rt<<1|1));
        return res;
    }
    int query_gcd(int L,int R,int l,int r,int rt){
        if(L>R) return 0;
        if(L<=l&&R>=r){
            return Gcd[rt];
        }
        int mid=l+r>>1,res=0;
        if(mid>=L) res=gcd(res,query_gcd(L,R,l,mid,rt<<1));
        if(mid<R) res=gcd(res,query_gcd(L,R,mid+1,r,rt<<1|1));
        return res;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        build(1,n,1);
        while(m--){
            int op,l,r,val;
            scanf("%d%d%d",&op,&l,&r);
            if(op==1){
                scanf("%d",&val);
                update(l,val,1,n,1);
                if(r<n) update(r+1,-val,1,n,1);
            }else if(op==2){
                printf("%d
    ",max(-query_min(l+1,r,1,n,1),query_max(l+1,r,1,n,1)));
            }else{
                printf("%d
    ",abs(gcd(query_sum(1,l,1,n,1),query_gcd(l+1,r,1,n,1))));
            }
        }
        return 0;
    }


  • 相关阅读:
    查看服务器
    AspectJ JoinPoint及ProceedingJoinPoint 简要api文档
    shrio的springboot完整配置
    shiro配置springboot的基本配置
    shiro的ssm集成和简单的开发尝试
    编写高质量的Python代码系列(八)之部署
    编写高质量的Python代码系列(七)之协作开发
    编写高质量的Python代码系列(六)之内置模块
    编写高质量的Python代码系列(五)之并发与并行
    编写高质量的Python代码系列(四)之元类及属性
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/11187320.html
Copyright © 2020-2023  润新知