Orac and LCM cf地址
For the multiset of positive integers s={s1,s2,…,sk}, define the Greatest Common Divisor (GCD) and Least Common Multiple (LCM) of s as follow:
gcd(s) is the maximum positive integer x, such that all integers in s are divisible on x.
lcm(s) is the minimum positive integer x, that divisible on all integers from s.
For example, gcd({8,12})=4,gcd({12,18,6})=6 and lcm({4,6})=12. Note that for any positive integer x, gcd({x})=lcm({x})=x.
Orac has a sequence a with length n. He come up with the multiset t={lcm({ai,aj}) | i
Input
The first line contains one integer n (2≤n≤100000).
The second line contains n integers, a1,a2,…,an (1≤ai≤200000).
Output
Print one integer: gcd({lcm({ai,aj}) | i
Examples
inputCopy
2
1 1
outputCopy
1
inputCopy
4
10 24 40 80
outputCopy
40
inputCopy
10
540 648 810 648 720 540 594 864 972 648
outputCopy
54
Note
For the first example, t={lcm({1,1})}={1}, so gcd(t)=1.
For the second example, t={120,40,80,120,240,80}, and it’s not hard to see that gcd(t)=40.
题目大意: 两两求最小公倍数,然后得到集合,求最大公因数。
思路: 求质因数次小的指数。
注意:当有某个质因数的个数为n的的时候,应该any*=次小指数
当为n-1的时候 应该为any*=最小指数。
直接把0算进去应该不用考虑这两种情况了
我的代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f3f3f3f3f
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define re register
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(a) ((a)&-(a))
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
#define fi first
#define rep(i,n) for(int i=0;(i)<(n);i++)
#define rep1(i,n) for(int i=1;(i)<=(n);i++)
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > pii;
const ll mod=104857601;
const int N =2e5+10;
const double eps = 1e-6;
const double pi=acos(-1);
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int dx[4]={-1,0,1,0} , dy[4] = {0,1,0,-1};
int a[N];
int p[N], cnt;
bool st[N];
void get_primes(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) p[cnt ++ ] = i;
for (ll j = 0; p[j] <= n / i; j ++ )
{
st[p[j] * i] = true;
if (i % p[j] == 0) break;
}
}
}
int pow1(int a,int b)
{
ll any=1;
while(b)
{
if(b&1) any*=a;
a*=a;
b>>=1;
}
return any;
}
int d1[N];
int d2[N];
int d3[N];
int main()
{
get_primes(N);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
if(n==2)
{ printf("%lld",ll(a[1]/gcd(a[1],a[2]))*a[2]);
return 0;
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<cnt;j++)
{
if(a[i]<p[j]||a[i]<p[j]*p[j]) break;
if(a[i]%p[j]==0)
{
int x=0;
d3[p[j]]++;
while(a[i]%p[j]==0)
{
a[i]/=p[j];
x++;
}
if(x<=d1[p[j]]||d1[p[j]]==0)
{
d2[p[j]]=d1[p[j]];
d1[p[j]]=x;
}
else if(x<d2[p[j]]||d2[p[j]]==0)
{
d2[p[j]]=x;
}
}
}
if(a[i]>1)
{
d3[a[i]]++;
int x=1;
if(x<=d1[a[i]]||d1[a[i]]==0)
{
d2[a[i]]=d1[a[i]];
d1[a[i]]=x;
}
else if(x<d2[a[i]]||d2[a[i]]==0)
{
d2[a[i]]=x;
}
}
}
ll any=1;
for(int i=0;i<200000;i++)
{
if(d3[i]==n) any*=pow1(i,d2[i]);
else if(d3[i]==n-1) any*=pow1(i,d1[i]);
}
printf("%lld\n",any);
return 0;
}
大神代码:优美的求次小指数,在最小指数的基础上求。
#include
using namespace std;
typedef long long ll;
ll n,d[100007],a,b;
int main()
{
cin>>n;
cin>>d[1]>>d[2];
a=__gcd(d[1],d[2]);
b=d[1]*d[2];
for(int i=3;i<=n;i++){
cin>>d[i];
b=__gcd(a*d[i],b);
a=__gcd(a,d[i]);
}
cout<<b/a;
return 0;
}