Ned 的难题

Posted 无尽的蓝黄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ned 的难题相关的知识,希望对你有一定的参考价值。

题目

技术分享图片

分析

对于20%,\[ans=\Pi_{i=1}^{n}\Pi_{j=i}^{n}gcd(a_{i},a_{i+1},...,a_{j-1},a_{j})\]
显然这是会超时的,那么我们换个方法,
假设当前做到\(i\),设\(b_{j}表示gcd(a_{j},a_{j+1},...,a_{i-1})\)
那么
\[ans=ans*a_{i}*\Pi_{j=1}^{i-1}gcd(b_{j},a_{i})\]
发现\(b\)一定是单调递增的,而且,其中有很多的\(b_{j}\)是相同的。接着,每次递增都至少是翻倍的。
那么,就可以加个链表。
时间复杂度\(O(NlogN)\)

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483647;
const long long mo=1000000009;
const long long N=50005;
using namespace std;
long long a[N],ans=1,n,m,b[N],tot,v[N];
long long gcd(long long x,long long y)
{
    return x==0?y:gcd(y%x,x);
}
long long mi(long long x,long long y)
{
    long long sum=1;
    while(y)
    {
        if(y&1) sum=sum*x%mo;
        x=x*x%mo;
        y/=2;
    }
    return sum;
}
int main()
{
    freopen("ned.in","r",stdin);
    freopen("ned.out","w",stdout);
    scanf("%lld",&n);
    for(long long i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        b[i]=a[i];
        v[i]=i;
    }
    ans=a[1];
    for(long long i=2;i<=n;i++)
    {
        ans=ans*a[i]%mo;
        long long k=i;
        for(long long j=i-1;j;j=v[j]-1)
        {
            b[j]=gcd(b[j],a[i]);
            if(b[j]==b[k]) 
                v[k]=v[j];
            ans=ans*mi(b[j],j-v[j]+1)%mo;
            k=j;
        }
    }
    printf("%d",ans);
}

以上是关于Ned 的难题的主要内容,如果未能解决你的问题,请参考以下文章

解决方案电影标题中缺少代码的片段,完成挑战更多[关闭]

POJ-1258-Agri Ned

985大学的高材生只会写代码片段,丢人吗?

985高校的高材生只会写代码片段,丢人吗?

985大学的高材生只会写代码片段,丢人吗?

985大学的高材生只会写代码片段,丢人吗?