Orac and LCM #641(div2) c题--求质因数次小指数

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;
}

你可能感兴趣的:(思维,数学)