The Factor
Time Limit: 1 Sec
Memory Limit: 256 MB
题目连接
http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=628&pid=1001Description
有一个数列,FancyCoder沉迷于研究这个数列的乘积相关问题,但是它们的乘积往往非常大。幸运的是,FancyCoder只需要找到这个巨大乘积的最小的满足如下规则的因子:这个因子包含大于两个因子(包括它本身;比如,4有3个因子,因此它是满足这个要求的一个数)。你需要找到这个数字并输出它。但是我们知道,对于某些数可能没有这样的因子;在这样的情况下,请输出-1.
Input
输入文件的第一行有一个正整数T (1 le T le 15)T (1≤T≤15),表示数据组数。
接下去有TT组数据,每组数据的第一行有一个正整数n (1 le n le 100)n (1≤n≤100).
第二行有nn个正整数a_1, ldots, a_n (1 le a_1, ldots ,a_n le 2 imes 10^9)a1,…,an (1≤a1,…,an≤2×109), 表示这个数列。
Output
输出TT行TT个数表示每次询问的答案。
Sample Input
2 3 1 2 3 5 6 6 6 6 6
Sample Output
6 4
HINT
题意
给你一个n个数
有一个数是由这N个数乘起来的,然后让你输出这个数的不是素数的最小的因子
题解:
对于每一个数都分解质因数,然后取最小的两个乘起来就好了
//1085422276 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> #include<map> #include<bitset> #include<set> #include<vector> using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,127,sizeof(a)); #define TS printf("111111 "); #define FOR(i,a,b) for( int i=a;i<=b;i++) #define FORJ(i,a,b) for(int i=a;i>=b;i--) #define READ(a,b,c) scanf("%d%d%d",&a,&b,&c) #define inf 100000 #define maxn 300000 inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } //**************************************** ///**************************************************************** /// Miller_Rabin 算法进行素数测试 ///速度快,而且可以判断 <2^63的数 //**************************************************************** const int S=20;///随机算法判定次数,S越大,判错概率越小 ///计算 (a*b)%c. a,b都是long long的数,直接相乘可能溢出的 /// a,b,c <2^63 long long mult_mod(long long a,long long b,long long c) { a%=c; b%=c; long long ret=0; while(b) { if(b&1){ret+=a;ret%=c;} a<<=1; if(a>=c)a%=c; b>>=1; } return ret; } ///计算 x^n %c long long pow_mod(long long x,long long n,long long mod)//x^n%c { if(n==1)return x%mod; x%=mod; long long tmp=x; long long ret=1; while(n) { if(n&1) ret=mult_mod(ret,tmp,mod); tmp=mult_mod(tmp,tmp,mod); n>>=1; } return ret; } ///以a为基,n-1=x*2^t a^(n-1)=1(mod n) 验证n是不是合数 ///一定是合数返回true,不一定返回false bool check(long long a,long long n,long long x,long long t) { long long ret=pow_mod(a,x,n); long long last=ret; for(int i=1;i<=t;i++) { ret=mult_mod(ret,ret,n); if(ret==1&&last!=1&&last!=n-1) return true;//合数 last=ret; } if(ret!=1) return true; return false; } /// Miller_Rabin()算法素数判定 ///是素数返回true.(可能是伪素数,但概率极小) ///合数返回false; bool Miller_Rabin(long long n) { if(n<2)return false; if(n==2)return true; if((n&1)==0) return false;//偶数 long long x=n-1; long long t=0; while((x&1)==0){x>>=1;t++;} for(int i=0;i<S;i++) { long long a=rand()%(n-1)+1;///rand()需要stdlib.h头文件 if(check(a,n,x,t)) return false;//合数 } return true; } //************************************************ ///pollard_rho 算法进行质因数分解 //************************************************ long long factor[100000];///质因数分解结果(刚返回时是无序的) int tol;///质因数的个数。数组小标从0开始 long long gcd(long long a,long long b) { if(a==0)return 1;//?????? if(a<0) return gcd(-a,b); while(b) { long long t=a%b; a=b; b=t; } return a; } long long Pollard_rho(long long x,long long c) { long long i=1,k=2; long long x0=rand()%x; long long y=x0; while(1) { i++; x0=(mult_mod(x0,x0,x)+c)%x; long long d=gcd(y-x0,x); if(d!=1&&d!=x) return d; if(y==x0) return x; if(i==k){y=x0;k+=k;} } } ///对n进行素因子分解 ll Div[1000000]; int tot=0; void findfac(long long n) { if(Miller_Rabin(n))//素数 { Div[tot++]=n; return; } long long p=n; while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1); findfac(p); findfac(n/p); } //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ll p[maxn]; int main() { int t=read(); while(t--) { int n=read(); memset(Div,0,sizeof(Div)); tot=0; for(int i=1;i<=n;i++) { scanf("%I64d",&p[i]); if(p[i]!=1) findfac(p[i]); } sort(Div,Div+tot); if(tot<=1) printf("-1 "); else { cout<<Div[0]*Div[1]<<endl; } } }