CodeForces1325E Ehab‘s REAL Number Theory Problem

Original title link

Locke's
CF's
VJ's

Title description

I can't write a shorter meaning QwQ, Luo Gu is too strong Orz. Only quoted here:

Give some numbers, each of which has no more than 7 77. Find the minimum number to choose so that the product is a perfect square. No solution output− 1 -11

Problem solving ideas

There are two breakthrough points, otherwise you will not be able to withdraw.
First decompose each number into prime factors. If the order of a certain prime factor is even, then ignore it, because the order of each prime factor of the squared number is even, otherwise, it is necessary to find the order of the prime factor of which other number is also odd, and the two multiplication becomes even. Up. But the number of counts is too much, if the enumeration is sure TLE TLET L E . Then we have the first breakthrough point:
up to7 77 factors
indicate that each number has at most two different prime factors, because if there are three different prime factors then according to the factor theorem, there are2 3 = 8 2^3=823=8 factors, greater than7 7Seven . There are only two prime factors, much like an edge connecting two points, so each prime factor can be regarded as a point, and then two different prime factors are connected to an undirected edge. Because we are dealing with prime factors with odd degrees, if there are prime factors with even degrees, use1 11 instead of this position. Consider how to calculate whether it is feasible after having this graph. If you choose an edge, you have chosen this number. If you want to be a complete square number, then every prime factor with an odd degree must be selected even times, then the selected graph The degree of each point in is an even number: it is a ring! So this question becomes to find a minimum ring. Because we want to judge whether the graph is connected, we need to enumerate from each prime number, usingbfs bfsb f s finds the ring. But there are many prime numbers, and I needTLE TLET L E . Let’s come to the second breakthrough point:
each number is up to1 0 6 10^6106
This feels like an ordinary data range, but it is not simple. We know that each numbernnn will not have two or more prime factors greater thann \sqrt nn , Because if there are two or more, then two numbers multiply greater than nnn , but it should bennFactor of n , more thannnn is small and contradictory. Therefore, when constructing a map like this, at least one of the two points connected by each edge is in1000 1000Within 1 0 0 0 . So the starting point of the enumeration is1000 10001 0 0 0 is enough, the bigger one must have been traversed, there is no need to traverse. Because prime numbers are a bit large, all prime numbers are discretized.

Ugly code

#include<bits/stdc++.h>
using namespace std;
const int NN=1e6+4;
int prime[NN],num[NN],head[NN],e[NN*2],ne[NN*2],idx,d[NN];
bool vis[NN];
void add(int u,int v)
{
    
    
	e[++idx]=v;
	ne[idx]=head[u];
	head[u]=idx;
}
int main()
{
    
    
	int cnt=0,maxs=1;
	num[1]=1;
	for(int i=2;i<NN;i++)
	{
    
    
		if(!vis[i])
		{
    
    
			prime[++cnt]=i;
			num[i]=cnt+1;
			if(i<1000)
				maxs++;
		}
		for(int j=1;i*prime[j]<NN;j++)
		{
    
    
			vis[i*prime[j]]=true;
			if(!(i%prime[j]))
				break;
		}
	}
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
    
    
		int x,q=1,p=1;
		scanf("%d",&x);
		for(int i=1;prime[i]*prime[i]<=x;i++)
		{
    
    
			int res=0;
			while(!(x%prime[i]))
			{
    
    
				res++;
				x/=prime[i];
			}
			if(res&1)
			{
    
    
				if(q>1)
					p=prime[i];
				else
					q=prime[i];
			}
		}
		if(x>1)
		{
    
    
			if(q>1)
				p=x;
			else
				q=x;
		}
		add(num[q],num[p]);
		add(num[p],num[q]);
	}
	int ans=1e9;
	for(int s=1;s<=maxs;s++)
	{
    
    
		queue<pair<int,int> >q;
		q.push(make_pair(s,0));
		memset(d,-1,sizeof(d));
		d[s]=0;
		while(q.size())
		{
    
    
			int u=q.front().first,fa=q.front().second;
			q.pop();
			for(int i=head[u];i;i=ne[i])
			{
    
    
				int v=e[i];
				if(v==fa)
					continue;
				if(d[v]==-1)
				{
    
    
					d[v]=d[u]+1;
					q.push(make_pair(v,u));
				}
				else
					ans=min(ans,d[u]+d[v]+1);
			}
		}
	}
	if(ans>n)
		printf("-1");
	else
		printf("%d",ans);
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44043668/article/details/109147562