Date:2022.01.05
题意:给定一串数,这串数包含除了1和x本身外x的所有约数,求能不能得出一个x,或得不出一个x(输出-1)。
T=25,n=300,m=10610^6106
思路①:
首先,x什么时候不存在?
题目说明是除了1和x的所有约数,因此个数一定是x的约数个数-2,因此得到x的所有质因子后,即求出x的约数个数即可判断x是否正确,而x的所有质因子一定在其所有约数中,因此可行。
其次,x怎么得出?
毫无疑问,x是所有数的倍数,因此x一定是所有数的所有质因子的最高次幂的倍数,由此便能对每个数分解质因子,求出所有数中每个质因子的最高次幂,试除法筛一遍质因子,O(T∗n∗mO(T*n*\sqrt{m}O(T∗n∗m)。此时我们统计出了所有质因子的最高次幂,欧拉筛打一个m=106m=10^6m=106以内的质数表(根据质数定理,质数约等于m/lnmm/lnmm/lnm不超过10510^5105个,因此结合t不超过O(T∗m/lnm)O(T*m/lnm)O(T∗m/lnm)),用于累乘每一个质因子的最高次幂。但是累乘完得出的不一定是x(因为数列中的最大元素可能等于当前piaip_i^{a_i}piai的累乘结果,因此不是x),那此时怎么办?要让x最小,因此一定乘的是最小的那个质因子,这样得出的一定是x!因此,我们只需要判断累乘结果是否为数列中最大元素,若是,则再乘一个最小质因子后变为x;若不是,则累乘结果一定是x。有点啰嗦,看代码吧。
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
const int N = 1e6+10;
typedef unsigned long long LL;
LL a[N];
LL t,n,m;
LL cnt,prime[N];
bool st[N];
void init(int n)
{
for(int i=2;i<=n;i++)
{
if(!st[i]) prime[cnt++]=i;
for(int j=0;prime[j]<=n/i;j++)
{
st[prime[j]*i]=true;
if(i%prime[j]==0) break;
}
}
}
LL qmi(LL a,LL k)
{
LL res=1;
while(k)
{
if(k&1) res*=a;
a=a*a;k>>=1;
}
return res;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
init(N-1);
cin>>t;
while(t--)
{
map<LL,LL>q;
cin>>n;LL maxx=-1e18;
for(int i=1;i<=n;i++)
{
cin>>a[i];maxx=max(a[i],maxx);
int m=a[i];
for(int j=2;j<=m/j;j++)
{
if(m%j==0)
{
LL s=0;
while(m%j==0) {s++;m/=j;}
q[j]=max(q[j],s);
}
}
if(m>1) q[m]=max(q[m],(LL)1);
}
LL res=1,ans=1;//res:累乘结果 ans:所求约数个数
bool flag=true;LL xx=0;
for(int i=0;i<cnt;i++)
{
if(q[prime[i]]>0)
{
if(!flag)//这里简化了,最小质因子先不乘进去,先判断累乘完是不是x
ans=ans*(q[prime[i]]+1);
if(flag)
{xx=prime[i];flag=false;}
res=res*qmi(prime[i],q[prime[i]]);
}
}
if(maxx<res)
{
ans=ans*(q[xx]+1);//累乘结果即为x,只乘一个最小质因子即可
if(n!=ans-2) {cout<<-1<<endl;continue;}
cout<<res<<endl;
}
else
{
ans=ans*(q[xx]+2);//累乘结果在数列中,多乘一个最小质因子
if(n!=ans-2) {cout<<-1<<endl;continue;}
cout<<res*xx<<endl;
}
}
return 0;
}

该博客主要探讨了一道数学与算法相结合的问题,涉及数论和质因数分解。给定一个数列,包含某个数x的所有非1非自身的约数,目标是找出可能的x值或者输出-1表示无法确定。博主通过分析得出,x的约数个数减2应当等于数列的长度,并提出了通过欧拉筛和质因子分解的方法来寻找x。在代码实现中,博主使用了质数表、高精度快速幂运算以及试除法,通过判断累乘结果是否等于数列最大值来确定x。

1209

被折叠的 条评论
为什么被折叠?



