CodeForces1325 E. Ehab's REAL Number Theory Problem (converted to the required minimum cycle problems + bfs smallest ring)

Meaning of the questions:

To a length n array a, the array elements satisfy the condition: Each number only a maximum of seven factors
now want you to elect a period of sub-sequences, sequences satisfying product is a perfect square, the minimum length of the sequence is asked how much , the minimum output length, no solution outputs -1
data range: n <= 1e5, a ( i) <= 1e6

Ideas:

Perfect square that is a power of the prime factors of the number are even.

Only a maximum number of seven factors, can have up to only two prime factors, because the number three germplasm factor of at least eight factors.

If a number is not odd powers of prime factors, then it is a perfect square, you can output 1
if an odd number has a power of prime factors, so that the quality factor and point 1 undirected edges even
if a there are number two for the odd powers of prime factors, so that between the two prime factors even undirected edges

Graphs smallest ring is the answer.

Calculate the minimum common ring is Floyd, but the complexity is too high, this is clearly not question.

Considering the right side is 1, it is possible to enumerate all points as a starting point to calculate the minimum ring + bfs.
But as a starting point to enumerate all the points will be timed out.
Considering the maximum data range, because the range of the maximum data 1e6, 1e6 is larger than the root (i.e., greater than the point 1e3), and the same can not be contiguous points greater than 1e3 (impossible because a number greater than two of qualitative 1e3 factor), and may only be connected point is less than 1e3, thus requiring only enumerate less 1e3 point as a start point on the line.

PS:
bfs seeking smallest ring is the first time I saw, not really understand the principle.
Videos FIG bfs hierarchical bit of a search to find that when x of v has been found over time, the ring should be the minimum d (x) + d (v ) + 1-d (LCA (x, v)), but we are directly code d (x) + d (v ) +1 take min, no tube behind the LCA, found little thought for a moment because the number of the root node to enumerate all, always to their enumeration LCA as the root, this time can be the above formula can be removed later in a LCA, that is to get direct access to the correct answer will always min.

For this question, it does not enumerate also be greater than for 1e3, because he is connected to enumerate the points as LCA can calculate the answer.

code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=1e6+5;
int head[maxm],nt[maxm<<1],to[maxm<<1],w[maxm<<1],cnt,idx;
int d[maxm],mark[maxm];
int ans=1e9;
int n;
void add(int x,int y,int z){
    cnt++;nt[cnt]=head[x];head[x]=cnt;to[cnt]=y,w[cnt]=z;
}
bool isprime(int x){
    for(int i=2;i*i<=x;i++){
        if(x%i==0)return 0;
    }
    return 1;
}
void bfs(int st){
    queue<int>q;
    q.push(st);
    memset(d,-1,sizeof d);
    for(int i=1;i<=idx;i++)mark[i]=0;//清空边标记
    d[st]=0;
    while(!q.empty()){
        int x=q.front();
        q.pop();
        for(int i=head[x];i;i=nt[i]){
            if(mark[w[i]])continue;//回边跳过
            mark[w[i]]=1;
            int v=to[i];
            if(d[v]==-1){
                d[v]=d[x]+1;
                q.push(v);
            }else{
                ans=min(ans,d[v]+d[x]+1);
            }
        }
    }
}
signed main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++){
        int x;
        scanf("%lld",&x);
        int a=0,b=1;
        for(int j=2;j*j<=x;j++){
            if(x%j==0){
                int cnt=0;
                while(x%j==0){
                    cnt++;
                    x/=j;
                }
                if(cnt%2){
                    if(!a)a=j;
                    else b=j;
                }
            }
        }
        if(x!=1){
            if(!a)a=x;
            else b=x;
        }
        if(!a){//如果本身就是完全平方数,则答案为1
            puts("1");
            return 0;
        }
        add(a,b,idx);
        add(b,a,idx);
        idx++;
    }
    for(int i=1;i<=1000;i++){//max(a[i])=1e6 -> sqrt(max(a[i]))=1e3
        if(isprime(i)){
            bfs(i);
        }
    }
    if(ans==1e9)ans=-1;
    printf("%lld\n",ans);
    return 0;
}

Published 430 original articles · won praise 36 · views 20000 +

Guess you like

Origin blog.csdn.net/weixin_44178736/article/details/104916693