Ehab's REAL Number Theory Problem-CF1325E(补)
题意:
给你一串数,每个数的因子不超过7个,求最少选出多少个数,使得他们的乘积为完全平方数。若无解则输出-1
链接: https://codeforces.com/contest/1325/problem/E
思路:
参考博客 https://www.luogu.com.cn/blog/0408Dodgemin/cf1325e-ti-xie#
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=1e6+5; const int INF=0x3f3f3f3f3f3f3f; bool notprime[MAXN],visit[MAXN]; int prime[MAXN],tot,a[MAXN]; int head[MAXN],cnt; vector<int>v[MAXN]; int dis[MAXN],ans=INF,max_; struct node { int to,nxt; node(){} node(int x,int y):to(y),nxt(head[x]){} }e[MAXN]; void add(int x,int y) { e[cnt]=node(x,y); head[x]=cnt++; e[cnt]=node(y,x); head[y]=cnt++; } void get_prime(int x) { notprime[1]=1; prime[tot++]=1; for(int i=2;i<=x;i++) { if(!notprime[i]) prime[tot++]=i; for(int j=1;j<tot&&i*prime[j]<=x;j++) { notprime[prime[j]*i]=1; if(i%prime[j]==0) break; } } } void bfs() { for(int i=0;i<tot;i++) { if((ll)prime[i]*(ll)prime[i]>max_) break; memset(dis,0x3f,sizeof(dis)); dis[prime[i]]=0; queue<pair<int,int> >q; q.push(make_pair(prime[i],-1)); while(!q.empty()) { pair<int,int> temp=q.front();q.pop(); int u=temp.first,fa=temp.second; for(int i=head[u];~i;i=e[i].nxt) { int nx=e[i].to; if(nx==fa)continue; if(dis[nx]==INF&&nx!=prime[i]) { dis[nx]=dis[u]+1; q.push(make_pair(nx,u)); } else { ans=min(ans,dis[u]+dis[nx]+1); } } } } if(ans==INF)ans=-1; } void divid(int x) { int temp=x; for(int i=2;i*i<=x;i++) { int count_=0; if(x%i==0) { while(x%i==0) { x/=i;count_++; } if(count_&1) { v[temp].push_back(i); } } } if(!notprime[x]) v[temp].push_back(x); } int main() { ios::sync_with_stdio(false); cin.tie(0); memset(head,-1,sizeof(head)); //int max_=0; int n;cin>>n; for(int i=1;i<=n;i++){ cin>>a[i];max_=max(max_,a[i]); } get_prime(max_); for(int i=1;i<=n;i++) { if(!visit[a[i]]) divid(a[i]); visit[a[i]]=1; } //cout<<v[2][0]<<" "<<v[3][0]<<" "<<v[6][1]<<endl; for(int i=1;i<=n;i++) { if(v[a[i]].empty()) { cout<<"1"<<endl;return 0; } if(v[a[i]].size()==1) v[a[i]].push_back(1); add(v[a[i]][0],v[a[i]][1]); } //cout<<ans<<endl; bfs(); cout<<ans<<endl; return 0; }