• CF1349A 【Orac and LCM】


    题目大意

    给你一个长度为 (n) 的集合 ({a_1 , a_2;...;a_n}),请你求出 (gcd{ ext{lcm}(a_i,a_j);|;i<j })

    思路

    众所周知,( ext{lcm}(a,b)=dfrac{a imes b}{gcd(a,b)})

    所以原式可以化为 (gcd{ dfrac{a_i imes a_j}{gcd(a_i,a_j)};|;i < j })

    (gcd(a_i,a_j)) 提出可得 (dfrac{gcd{ a_i imes a_j;|;i < j }}{gcd(a_1,a_2 ;...;a_n)})

    (gcd(a_1,a_2 ;...;a_n)) 可以线性求出,那么问题就转化成了如何快速求 (gcd{ a_i imes a_j;|;i < j })

    设我们每次枚举到第 (i) 个数 (a_i)(x),那么可以将 (gcd{ x imes a_j;|;i < j }) 中的 (x) 提出,就可以得到 (x imes gcd(a_{i+1},a_{i+2};...;a_{n}))

    可以预处理出一个后缀 (gcd) ,然后枚举 (a_i) 计算答案即可。

    时间复杂度:常数极小的 ( ext{O}(n log a_{max}))

    记得开 ( ext{long long}) ((

    Code

    #include<bits/stdc++.h>
    #define LL long long
    
    using namespace std;
    
    LL read()
    {
    	LL ans=0,f=1;
    	char c=getchar();
    	while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    	while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    	return ans*f;
    }
    
    const LL N=1e5+5;
    LL n,a[N],b[N],ans;
    
    int main()
    {
    	n=read();
    	for(LL i=1;i<=n;++i)
    		a[i]=read();
    	for(LL i=n;i>=1;--i)
        // 预处理后缀 gcd
    		b[i]=__gcd(b[i+1],a[i]);
    	for(LL i=1;i<=n;++i)
        // 计算 gcd { ai , aj | i < j }
    		ans=__gcd(ans,a[i]*b[i+1]);
        // 答案就是 gcd { ai , aj | i < j } / gcd ( a1 , a2 ... an )
    	printf("%lld
    ",ans/b[1]);
    	return 0;
    } 
    
  • 相关阅读:
    [Linux起步]常用命令
    Eclipse被SD杂志评为最佳开源工具
    [一点一滴学英语]20050921
    [一点一滴学英语]20050920
    [一点一滴学英语]20050919
    Longhorn (Vista) 推迟发布的背后
    最快速度找到内存泄漏
    重载(overload)、覆盖(override)、隐藏(hide) 详解
    HTTP请求和响应格式
    Skia之四——SkGradientShader篇
  • 原文地址:https://www.cnblogs.com/blackbird137/p/13550393.html
Copyright © 2020-2023  润新知