上海市计算机学会竞赛平台2025年5月月赛丙组相等数组

题目描述

Eve 有一个长度为 nn 的数组 aa 以及一个常数 m≥2m≥2,他知道对于任意的 1≤i≤n1≤i≤n,都有 2≤ai≤m2≤ai​≤m。

Eve 觉得数组里一定要有全部相等的元素,所以他想通过以下操作把数组里的元素变得全部相等:

  • 选定一个整数 2≤t≤m2≤t≤m,然后令每一个 aiai​ 都变为 gcd⁡(ai,t)gcd(ai​,t),其中 gcd⁡(x,y)gcd(x,y) 表示 x,yx,y 的最大公因数,例如 gcd⁡(4,6)=2,gcd⁡(15,21)=3gcd(4,6)=2,gcd(15,21)=3。

请帮助 Eve 求出最少操作多少次能够使得数组里元素全部相等,如果无论多少次操作都不能达成目标,则输出 −1−1。

输入格式

第一行一个整数 TT 表示数组组数,对于每组数据:

第一行两个正整数 n,mn,m。

第二行 nn 个整数 a1,a2,…,ana1​,a2​,…,an​。

输出格式

对于每组数据,如果能使得数组元素全相等,输出一行一个非负整数表示最小操作次数,否则输出一行 -1

数据范围

对于 30%30% 的数据,∑n≤20∑n≤20,m≤20m≤20。

对于 60%60% 的数据,∑n≤3×105∑n≤3×105,m≤1000m≤1000。

对于 100%100% 的数据,1≤T≤1051≤T≤105,1≤n≤1051≤n≤105,∑n≤3×105∑n≤3×105,2≤m≤1062≤m≤106,2≤ai≤m2≤ai​≤m。

样例数据

输入:

2
3 343
343 343 343
5 100
4 8 12 16 20

输出:

0
1

说明:

对于第二组数据,取t=4操作一次即可使数组元素全变为4。

详见代码:

#include
using namespace std;
int t,n,m;
int a[100005];
vector  p;
bool b[1000005];
int c[1000005];
int main()
{
    for(long long i=2;i<=1000000;i++)
    {
        if (b[i]==0)
        {
            p.push_back(i);
            for(long long j=i*i;j<=1000000;j+=i)
            {
                b[j]=1;
            }
        }
    }
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        bool flag=1;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        int g=a[1];
        for(int i=1;i<=n;i++)
        {
            if (i>1&&a[i]!=a[i-1])
            {
                flag=0;
            }
            g=__gcd(g,a[i]);
        }
        if (flag==1)
        {
            cout<<0<<"\n";
            continue;
        }
        if (g>1)
        {
            cout<<1<<"\n";
            continue;
        }
        memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++)
        {
            for(int j=2;j*j<=a[i];j++)
            {
                while(a[i]%j==0)
                {
                    c[j]=1;
                    a[i]/=j;
                }
            }
            c[a[i]]=1;
        }
        flag=0;
        for(int i=0;i

你可能感兴趣的:(算法)