F.ケイトと不完全さ

タイトルポータル

トピック: 1からnまでのn個の数値で、k∈[2、n]の場合、n個の数値からk個の数値を取り出し、k個の数値に対してペアでgcdを実行し、gcdの最小最大値を出力します。

アイデア: gcdが必要なため、Ehrlichふるいの更新操作を考えることができます。iに遭遇するたびに、iの倍数をマークします。マークされた数字の中で、現在の最大の因数はiです。n内でふるいにかけた後、配列に格納されるのは、n内での最大の因子です。ただし、素数の場合、他の数値によるスクリーニングを受けていないため、配列は0を格納し、すべての0を1に置き換えて、配列n-1を小さいものから大きいものに出力します。

正確性の証明: 2つの数値gcdの最小値と最大値を求めるため、可能な限り素数を取得します。素数を取得した後、数値を取得すると、素数でない素数のペアが存在する必要があるため、答えを出そうとする必要があります小さくなります。つまり、最初に小さい方を取り、最後に小さい出力から大きい出力へと結論を出すことができます。

コード

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
const int inf=0x7fffffff;
const int mod=1e9+7;
const int eps=1e-6;
typedef long long ll;
typedef unsigned long long ull;
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl '\n'
#define null NULL
int ok[N];
signed main()
{
    IOS;
    int n;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        for(int j=i*2;j<=n;j+=i)
        {
            ok[j]=i;
        }
    }
    priority_queue<int,vector<int>,greater<int> >q;
    for(int i=2;i<=n;i++)
    {
        if(ok[i]==0)
        {
            q.push(1);
        }
        else
        {
            q.push(ok[i]);
        }
    }
    while(!q.empty())
    {
        cout<<q.top()<<' ';
        q.pop();
    }
    cout<<endl;
}
公開された93元の記事 ウォンの賞賛9 ビュー4203

おすすめ

転載: blog.csdn.net/Joker_He/article/details/105423207