zoukankan      html  css  js  c++  java
  • 【uoj#48】[UR #3]核聚变反应强度 数论

    题目描述

    给出一个长度为 $n$ 的数列 $a$ ,求 $a_1$ 分别与 $a_1...a_n$ 的次大公约数。不存在则输出-1。

    输入

    第一行一个正整数 $n$ 。

    第二行 $n$ 个用空格隔开的正整数,第 $i$ 个为 $a_i$ 。

    $nle 10^5,a_ile 10^{12}$

    输出

    一行 $n$ 个用空格隔开的整数,第 $i$ 个表示 $ ext{sgcd}(a_1,a_i)$ 。

    样例输入

    4
    12450 1 2 450

    样例输出

    6225 -1 1 75


    题解

    数论

    次大公约数显然是最大公约数除以它的最小质因子得到的结果。

    但是每次都求最大公约数,然后再找最小质因子的话,时间复杂度为 $O(nsqrt a)$ ,无法承受。

    考虑:每次都是用 $a_1$ 与其它数求次大公约数,而最大公约数的因子一定是两个数的因子。

    因此可以直接预处理出 $a_1$ 的所有质因子,然后每次枚举判断是否成立即可。

    由于质因子只有 $O(log a)$ 个,因此时间复杂度为 $O(sqrt a+nlog a)$ 

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    ll a[100010] , v[40];
    inline ll gcd(ll a , ll b)
    {
    	ll t;
    	while(b) t = a , a = b , b = t % b;
    	return a;
    }
    int main()
    {
    	int n , m = 0 , i , j;
    	ll t;
    	scanf("%d" , &n);
    	for(i = 1 ; i <= n ; i ++ ) scanf("%lld" , &a[i]);
    	for(i = 2 , t = a[1] ; 1ll * i * i <= t ; i ++ )
    	{
    		if(!(t % i))
    		{
    			v[++m] = i;
    			while(!(t % i)) t /= i;
    		}
    	}
    	if(t != 1) v[++m] = t;
    	for(i = 1 ; i <= n ; i ++ )
    	{
    		t = gcd(a[1] , a[i]);
    		for(j = 1 ; j <= m ; j ++ )
    		{
    			if(!(t % v[j]))
    			{
    				printf("%lld " , t / v[j]);
    				break;
    			}
    		}
    		if(j > m) printf("-1 ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Eclipse中配置约束(DTD,XSD)
    Eclipse集成tomcat
    java使用dom4j对XML进行CURD操作
    SQL数据库操作(CURD)
    Java-IO流总结
    Java-集合框架总结
    AES apache commons-crypto 对称加密
    Redis
    Axis2 客户端调用 设置超时时间
    Sybase 修改数据库默认排序
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8185409.html
Copyright © 2011-2022 走看看