Ehab's REAL Number Theory Problem CodeForces - 1325E
参考文章:https://oierwanhong.cc/2020/03/16/CF1325E/
每个数至多有个7约数,也就是每个数至多两个不同的质因数
如果某个数没有指数为奇数的质因子,那么它就是一个完全平方数,直接输出1
如果某个数只有1个指数为奇数的质因子,让这个质因子和"源点"1连无向边
某个数有两个指数为奇数的质因子,让这两个质因子间连无向边
然后分别bfs每个点,去求最小环
#include<set>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define f first
#define s second
#define pii pair<int,int>
#define int long long
int read()
{
int res=0,ch,flag=0;
if((ch=getchar())=='-') //判断正负
flag=1;
else if(ch>='0'&&ch<='9') //得到完整的数
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
}
const int N=1e6+7;
set<pii>ms;
int e[N],ne[N],h[N],idx;
void add(int a,int b) {
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
void add_edge(int u,int v) {
if(v<u)
swap(u,v);
if(ms.find({u,v})!=ms.end()) {
cout<<2<<endl;
exit(0);
}
ms.insert({u,v});
add(u,v);
add(v,u);
}
int dist[N],son[N];
int ans=0x3f3f3f3f;
void bfs(int S) {
memset(dist,0x3f,sizeof dist);
queue <int> q;
q.push(S);
dist[S] = 0;
vector <int> who;
while (q.size()) {
int u = q.front();
q.pop();
who.push_back(u);
for (int i=h[u]; i!=-1; i=ne[i]) {
int v=e[i];
if (dist[u] + 1 < dist[v]) {
dist[v] = dist[u] + 1;
if (u == S)
son[v] = v;
else
son[v] = son[u];
q.push(v);
} else if (u != S && v != S && son[u]!=son[v])
ans=min(ans,dist[u]+dist[v]+1);
}
}
}
signed main() {
memset(h,-1,sizeof h);
int n=read();
vector<pii>ed;
while(n--) {
int x=read();
vector<int>a;
for(int i=2; i*i<=x; i++) {
if(x%i==0) {
int p=0;
while(x%i==0) {
++p;
x/=i;
}
if(p&1)
a.push_back(i);
}
}
if(x>1)
a.push_back(x);
if(a.empty()) {
cout<<1<<endl;
exit(0);
} else if(a.size()==1)
ed.push_back({1,a[0]});
else if(a.size()==2)
ed.push_back({a[0],a[1]});
}
for(auto e:ed)
add_edge(e.f,e.s);
for(int u=1; u<=1007; u++)
bfs(u);
if(ans>=0x3f3f3f3f)
cout<<"-1"<<endl;
else
cout<<ans<<endl;
return 0;
}