E. Ehab's REAL Number Theory Problem
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given an array aa of length nn that has a special condition: every element in this array has at most 7 divisors. Find the length of the shortest non-empty subsequence of this array product of whose elements is a perfect square.
A sequence aa is a subsequence of an array bb if aa can be obtained from bb by deletion of several (possibly, zero or all) elements.
Input
The first line contains an integer nn (1≤n≤1051≤n≤105) — the length of aa.
The second line contains nn integers a1a1, a2a2, ……, anan (1≤ai≤1061≤ai≤106) — the elements of the array aa.
Output
Output the length of the shortest non-empty subsequence of aa product of whose elements is a perfect square. If there are several shortest subsequences, you can find any of them. If there's no such subsequence, print "-1".
Examples
input
Copy
3
1 4 6
output
Copy
1
input
Copy
4
2 3 6 6
output
Copy
2
input
Copy
3
6 15 10
output
Copy
3
input
Copy
4
2 3 5 7
output
Copy
-1
Note
In the first sample, you can choose a subsequence [1][1].
In the second sample, you can choose a subsequence [6,6][6,6].
In the third sample, you can choose a subsequence [6,15,10][6,15,10].
In the fourth sample, there is no such subsequence.
題意:給你n(n<=1e5)個數a[i](<=1e6),保證每個數有不超過7個因子,求最少選出多少個數,它們的乘積是完全平方數。
思路:
每個數不超過7個因子,那麼它的素因子最多隻有兩個(三個的話就有8個因子了),設爲x和y
那麼我們要使x,y的冪次變爲偶數。有以下幾種情況:
①這個數本身就是完全平方數,直接特判
②這個數含有一個冪次爲奇數的質因子x,建立邊(1,hash[x]) (由於質因子最大可達六位數,所以進行離散化處理)
③這個數含有兩個冪次爲奇數的質因子x,y,建立邊(hash[x],hash[y])
這樣,我們只要從建立的圖裏找到一個長度最小的環,就是答案。(因爲環中所有結點的度爲偶數,想想是不是)
但是直接枚舉每個點是O(n*n)的。考慮環中一定有數值小於1000的點,因此我們枚舉數值1000以下所有結點,從這些結點出發找最小環。
注意,找環的時候,不能用dfs(否則會wa在149組,dfs確實不能找出所有的環),要用bfs(類似於最短路思想)
代碼:
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
using namespace std;
const int maxn=1e6+5;
//const double pi=acos(-1.0);
//const double eps=1e-9;
//const ll mo=1e9+7;
int fa[maxn],dp[maxn];
int n,m,k,cnt,ans;
vector<int>vv[maxn],vc[maxn];
map<int,int>hs,mp;
map<pair<int,int>,int>mm;
void dfs(int u,int f){// 注意,dfs不對!!!!!!!!
dp[u]=dp[f]+1;
for(int i=0;i<vc[u].size();i++){
int v=vc[u][i];
if(v==f) continue;
//cout<<u<<" "<<v<<" & "<<dp[u]<<" "<<dp[v]<<endl;
if(dp[v]){
ans=min(ans,max(dp[u],dp[v])-min(dp[u],dp[v])+1);
}
else dfs(v,u);
}
}
int main(){
scanf("%d",&n);
ans=inf;
rep(i,1,n){
int x,ok=1;
scanf("%d",&x);
for(int j=2;j*j<=x;j++) if(x%j==0){
int cnt=1;x/=j;
while(x%j==0) {x/=j;cnt^=1;}
if(cnt) {vv[i].push_back(j);ok=0;}
}
if(x>1) vv[i].push_back(x);
if(ok&&x==1) {ans=1;}
}
if(ans==1) {puts("1");return 0;}
hs[1]=1;cnt=1;
rep(i,1,n){
if(vv[i].size()==1){
if(mp[vv[i][0]]) {ans=2;break;}
mp[vv[i][0]]=1;
if(!hs[vv[i][0]]) hs[vv[i][0]]=++cnt;
vc[1].push_back(hs[vv[i][0]]);
vc[hs[vv[i][0]]].push_back(1);
}
if(vv[i].size()==2){
int u=vv[i][0],v=vv[i][1];
if(u>v) swap(u,v);
pair<int,int> p=make_pair(u,v);
if(mm[p]) {ans=2;break;}
mm[p]=1;
if(!hs[u]) hs[u]=++cnt;
if(!hs[v]) hs[v]=++cnt;
vc[hs[u]].push_back(hs[v]);
vc[hs[v]].push_back(hs[u]);
}
}
/*rep(i,1,cnt) if(vc[i].size()){
for(int j=0;j<vc[i].size();j++)
cout<<vc[i][j]<<" ";
cout<<endl;
}*/
if(ans==2) {puts("2");return 0;}
queue<int>q;
for(int i=1;i<=1000;i++) if(hs[i]){
while(!q.empty()) q.pop();
rep(j,0,cnt) {fa[j]=0;dp[j]=inf;}
q.push(hs[i]);fa[hs[i]]=1;dp[hs[i]]=1;
while(!q.empty()){
int u=q.front();q.pop();
for(int j=0;j<vc[u].size();j++){
int v=vc[u][j];
if(fa[u]==v) continue;
//cout<<u<<" "<<v<<" * "<<dp[u]<<" "<<dp[v]<<endl;
if(dp[v]!=inf) ans=min(ans,dp[u]+dp[v]-1);
if(dp[v]>dp[u]+1){
dp[v]=dp[u]+1;
if(!fa[v]) {
fa[v]=u;
q.push(v);
}
}
}
}
}
//cout<<"***"<<endl;
if(ans==inf) puts("-1");
else printf("%d\n",ans);
return 0;
}