【UR #3】核聚变反应强度

Time Limit: 1 Sec  Memory Limit: 256 MB

题目连接

http://uoj.ac/problem/48

Description

著名核物理专家 Picks 提出了核聚变特征值这一重要概念。

核聚变特征值分别为 x 和 y 的两个原子进行核聚变,能产生数值为 sgcd(x,y) 的核聚变反应强度。

其中, sgcd(x,y) 表示 x 和 y 的次大公约数,即能同时整除 x,y 的正整数中第二大的数。如果次大公约数不存在则说明无法核聚变, 此时 sgcd(x,y)=−1。

现在有 n 个原子,核聚变特征值分别为 a1,a2,…,an。然后 Picks 又从兜里掏出一个核聚变特征值为 a1 的原子,你需要计算出这个原子与其它 n 个原子分别进行核聚变反应时的核聚变反应强度,即 sgcd(a1,a1),sgcd(a1,a2),…,sgcd(a1,an)。

Input

第一行一个正整数 n。

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

Output

一行 n 个用空格隔开的整数,第 i 个表示 sgcd(a1,ai)。

C/C++ 输入输出 long long 时请用 %lld。由于本题数据量较大,建议不要使用 cin/cout 进行输入输出。

Sample Input

4
12450 1 2 450

Sample Output

6225 -1 1 75

HINT

n≤105,ai≤1012

题意

题解:

算法一

对于 n=1 的数据,就是求一个数次大的约数。

众所周知一个数x的约数是成对出现的(d、xd),其中总有一个不超过x√。所以从1到a1−−√地枚举d就能找出所有a1的约数了。排序输出次大的即可。

复杂度:O(a√)
算法二

先找出a1的所有约数,然后枚举i,sgcd(a1,ai)显然也是a1的约数,所以枚举a1的所有约数,找到是ai约数的次大的即可。

复杂度:O(na√)
算法三

考虑分解质因子后:

a=px11px22...pxmm

b=py11py22...pymm

则:gcd(a,b)=pmin(x1,y1)1pmin(x2,y2)2...pmin(xm,ym)m

我们发现,a和b的公约数都一定是gcd(a,b)的约数。那么为了得到次大公约数,只需求出gcd(a,b),再除去一个最小的公共质因子即可。

对a1用O(a1−−√)的时间分解得到O(log(a1))个质因数,每次对于ai,先求出g=gcd(a1,ai),然后枚举a1的每个质因数,找到最小的能整除g那个,设其为p,g/p即为所求。(不存在则为输出−1)

复杂度:O(a√+nlog(a))
一个骗分算法

考虑算法二,我们预先对 a1 的约数们排好序,然后枚举 i,从约数表里每次二分到 gcd(a1,ai)所在位置,再往前枚举,找到第一个能整除ai的即为次大公约数。

虽然复杂度不靠谱,但是对于ai≤1012的范围实际运行速度十分优秀。需要构造针对的数据才能卡住。

还有另一个骗分算法,求出 gcd 然后暴力枚举最小质因子。好多人写这个啊……你们都没意识到复杂度不对么……放你们一马给了 80 分。

(有这种闲心的为啥不写正解啊,你们考虑过 maker 的感受吗!QAQ)

代码:

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 200001
#define mod 10007
#define eps 1e-9
int Res,Num;char C,CH[];
//const int inf=0x7fffffff; //无限大
const int inf=0x3f3f3f3f;
/* inline void P(int x)
{
Num=0;if(!x){putchar('0');puts("");return;}
while(x>0)CH[++Num]=x%10,x/=10;
while(Num)putchar(CH[Num--]+48);
puts("");
}
*/
//**************************************************************************************
inline ll read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void P(int x)
{
Num=;if(!x){putchar('');puts("");return;}
while(x>)CH[++Num]=x%,x/=;
while(Num)putchar(CH[Num--]+);
puts("");
}
ll gcd(ll a,ll b)
{
return b==?a:gcd(b,a%b);
}
ll a[maxn];
ll p[maxn];
int main()
{
int n=read();
for(int i=;i<n;i++)
scanf("%lld",&a[i]);
ll tot=;
ll x=a[];
for(ll i=;i<=sqrt(x);i++)
{
if(x%i==)
{
while(x%i==)x/=i;
p[tot++]=i;
}
}
for(int i=;i<n;i++)
{
ll d=gcd(a[],a[i]);
int flag=;
for(int j=;j<tot;j++)
{
if(d%p[j]==)
{
printf("%lld ",d/p[j]);
flag=;
break;
}
}
if(flag)
{
if(d!=)
printf("1 ");
else
printf("-1 ");
}
} }

uoj 48 核聚变反应强度 次小公因数的更多相关文章

  1. 【UOJ#48】【UR #3】核聚变反应强度(质因数分解)

    [UOJ#48][UR #3]核聚变反应强度(质因数分解) 题面 UOJ 题解 答案一定是\(gcd\)除掉\(gcd\)的最小质因子. 而\(gcd\)的最小值因子一定是\(a_1\)的质因子. 所 ...

  2. 【uoj#48】[UR #3]核聚变反应强度 数论

    题目描述 给出一个长度为 $n$ 的数列 $a$ ,求 $a_1$ 分别与 $a_1...a_n$ 的次大公约数.不存在则输出-1. 输入 第一行一个正整数 $n$ . 第二行 $n$ 个用空格隔开的 ...

  3. [UOJ #48]【UR #3】核聚变反应强度

    题目大意:给你一串数$a_i$,求$sgcd(a_1,a_i)$,$sgcd(x,y)$表示$x,y$的次大公约数,若没有,则为$-1$ 题解:即求最大公约数的最大约数,把$a_1$分解质因数,求出最 ...

  4. UOJ 48 次最大公约数

    次最大公约数 = gcd / 其中一个数质因数中最小的. gcd(42,12) = 6;    div(42) = 2*3*7   div(12) = 2^2*3 sgcd(42,12) = 6 / ...

  5. [UR #3] 核聚变反应强度

    次大公约数就是gcd再除以其最小质因子(如果有的话).可以发现要求的sgcd 的前身gcd都是a1的约数,所以把a1质因数分解直接做就行了. #include<bits/stdc++.h> ...

  6. [UOJ48] 核聚变反应强度

    QUQ 思路 求出a1的所有约数,与a1.ai放入同一数组: 求出gcd(a1,ai): 枚举约数,得出ans; 代码实现 #include<cmath> #include<cstd ...

  7. UOJ#48最大矩形面积

    题面 这是一道标准的单调栈的题目,但是由于题目的个例性,该题对于前后两数等于的情况并无额外处理,so也确实是让这题简单了一点 也没什么好说的直接上代码吧 #include<iostream> ...

  8. 【UOJ Round #3】

    枚举/二分 C题太神窝看不懂…… 核聚变反应强度 QwQ很容易发现次小的公约数一定是gcd的一个约数,然后……我就傻逼地去每次算出a[1],a[i]的gcd,然后枚举约数……这复杂度……哦呵呵... ...

  9. $2018/8/15 = Day \ \ 1$杂题整理

    \(\mathcal{Morning}\) \(Task1\)高精度\(\times\)高精度 哦呵呵--真是喜闻乐见啊,我发现这一部分比较有意思于是就打算整理下来233.窝萌现在有一个整数\(A = ...

随机推荐

  1. Lucene7.2.1系列(三)查询及高亮

    系列文章: Lucene系列(一)快速入门 Lucene系列(二)luke使用及索引文档的基本操作 Lucene系列(三)查询及高亮 一 准备 创建项目并添加Maven依赖 <dependenc ...

  2. weblogic性能监控

    1.

  3. shell source命令说明

    当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录:这时就想到用source命令,如:source /etc/profile对source进行了学习,并且用它与sh 执行脚本进行 ...

  4. 32.Longest Valid Parentheses---dp

    题目链接:https://leetcode.com/problems/longest-valid-parentheses/description/ 题目大意:找出最长的括号匹配的子串长度.例子:&qu ...

  5. effective c++读书笔记(一)

    很早之前就听过这本书,找工作之前读一读.看了几页,个人感觉实在是生涩难懂,非常不符合中国人的思维方式.之前也有博主做过笔记,我来补充一些自己的理解. 我看有人记了笔记,还不错:http://www.3 ...

  6. PYTHON学习(三)之利用python进行数据分析(1)---准备工作

    学习一门语言就是不断实践,python是目前用于数据分析最流行的语言,我最近买了本书<利用python进行数据分析>(Wes McKinney著),还去图书馆借了本<Python数据 ...

  7. (转载)使用curl 和 libjson 完成联网和数据解析

    转载地址:http://my.oschina.net/cocosgame/blog/71181 libjson 编译和使用 - 3. libjson的C接口 API http://blog.csdn. ...

  8. [笔记]用gdb调试core dump

    总是隔一段时间才写一次C++,有些东西老是用完就忘了……记一下如何用gdb来调试core dump免得到时候又忘记. 首先需要设置core file的大小,默认是0所以不设不会生成core file ...

  9. Java学习(基本语句,语法,变量)

    一.基本语法: public class Demo { //定义一个类 public static void main(String[] args) { //主方法,一切程序的起点 /* 在屏幕上打印 ...

  10. Hadoop案例(一)之日志清洗

    日志清洗案例 一. 简单解析版 1)需求 去除日志中字段长度小于等于11的日志. 2)输入数据 /Sep/::: +] "-" "Mozilla/4.0 (compati ...