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;
}

 

posted @ 2020-03-19 09:49  grass_lin  阅读(153)  评论(0编辑  收藏  举报