CodeForces1325 E. Ehabの実数論の問題(必要な最小サイクル問題に変換+最小環BFS)

質問の意味:

長さnは配列aに、配列の要素が条件を満たし:7つの要因の唯一最大の各数値は
、今あなたがサブシーケンスの期間を選出したい、製品を満たすシーケンスは完璧な正方形で、シーケンスの最小の長さはどれくらい聞かれます、最小の出力長、無溶液出力-1
データ範囲:N <= 1E5、( I)<= 1E6

アイデア:

数の素因数の力で完璧な四角でもあります。

7要因の唯一の最大数は、少なくとも8つの要素の数3遺伝資源ファクターので、2つだけ素因数まで持つことができます。

数は素因数のない奇妙な力であれば、それは完全な方形であり、出力できます1
奇数になるように品質係数とポイントが1つの無向辺にも、素因数の力を持っている場合
ならば数2は、ので、2個の素因数の間にも無向エッジこと、素因数の奇数力のためにそこにあります

グラフ最小のリングが答えです。

これは明らかに問題ではない、計算は最小の共通リングはフロイドですが、複雑さは高すぎます。

右側を考慮することは、最小リング+ BFSを計算するために、出発点としてすべての点を列挙することが可能である、1です。
しかし、すべての点を列挙するための開始点としてタイムアウトします。
最大データ範囲を考慮すると、最大データ1E6の範囲ため、1E6は、ルート(点1E3よりすなわち、より大きい)よりも大きく、同じCAN 1E3より連続点大きくならない(不可能質的1E3の2つよりも数大きいため因子)、およびのみ接続することができる点は、このようにライン上の開始点としてのみ列挙以下1E3点を必要とする、以下1E3です。

PS:
最小のリングを求めてBFSは本当に原則を理解していない、初めてのIソーです。
ビデオ図は、Vのxは時間をかけて発見された場合、リングが最小D(x)+ D(Vなければならないことを見つけるために検索の階層ビットをBFS )+ 1-D(LCA(X、V))、 しかし私たちに直接コードD(x)は+ D(Vあり )1 ルートノードの数がすべてを列挙するので、常に彼らの列挙に、一瞬のために少し考えを見つけ、テイク分、LCAの背後には、チューブrootとしてLCAは、この時間は、上記の式は常にをminになる正解への直接アクセスを得ることですLCA、中、後に除去することができますすることができます。

LCAが答えを計算することができますように彼はポイントを列挙するために接続されているので、この質問のために、それは列挙にも、1E3よりも大きくすることはできません。

コード:

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

公開された430元の記事 ウォン称賛36 ビュー20000 +

おすすめ

転載: blog.csdn.net/weixin_44178736/article/details/104916693