• 2019年华南理工大学程序设计竞赛(春季赛)-H-Parco_Love_GCD


    题目链接:https://ac.nowcoder.com/acm/contest/625/H

    题意:给定n个数(<=1e9)的序列,其中n<=5e5,求该序列所有子序列的对应的gcd对1e9+7取模后的值。

    思路:比赛的看错题了,以为是要求n个数任意两个数的gcd的和,怪样例QAQ。。不过就算我没看错题我可能也做不出来。先把n个数的公共gcd求出来,记为com。然后对每个子序列的起点往后求gcd,记为nwa,令 ans=(ans+nw)%Mod; 如果nw=com,就不用再循环了,ans=(ans+(n-j)*com)%Mod。这样做用两层循环也可以过,有点惊讶,n大小可是5e5,但想想之后觉得也没问题,他们的公共gcd--com很可能为1,只要求到1的时候break,复杂度应该会降很多。加上这道题的时间限制为3s,这样做就没问题了。另外我写的时候写太快,不小心把数组开成了5e5大小了,下标从1开始,然后T了,想不懂的是为什么会T,不应该是RE吗。。总之把数组开大一点很重要。

    AC代码:

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    
    inline LL readLL(){
        LL x=0;int f=0;char c=0;
        while(!isdigit(c)){f|=c=='-';c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    
    LL gcd(LL a,LL b){
        return b?gcd(b,a%b):a;
    }
    
    const int Mod=1000000007;
    LL n,ans,a[5000005],com;
    
    int main(){
        n=readLL();
        com=a[1]=readLL();
        for(int i=2;i<=n;++i){
            a[i]=readLL();
            com=gcd(com,a[i]);
        }
        for(int i=1;i<=n;++i){
            LL nw=a[i]; 
            for(int j=i;j<=n;++j){
                nw=gcd(nw,a[j]);
                ans=(ans+nw)%Mod;
                if(nw==com){
                    ans=(ans+(n-j)*com)%Mod;
                    break;
                }
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    Erlang顺序型编程
    [转]理解gen_server behaviour
    [转]Parsing Text and Binary Files With Erlang
    [转]Running Hadoop On Ubuntu Linux (SingleNode Cluster)
    [转]erlang 监督树
    [转]Erlang之IO编程
    [转]分段表
    [转]如何“打败”CAP定理
    [转]A Millionuser Comet Application with Mochiweb
    [转]消息队列软件大比拼
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10708738.html
Copyright © 2020-2023  润新知