CF1366D 题解

题意简述

$n(1\le n\le2\times10^5)$ 次询问,每次给出正整数 $x(2\le x\le 10^7)$,要求判断是否存在 $x$ 的 $2$ 个不为 $1$ 的因数 $d_1,d_2$,使得 $\gcd(d_1+d_2,x)=1$,若存在则输出解,不存在输出 $-1$。

题目分析

比较好推的结论题。先给出结论:当且仅当 $x=p^k$($p$ 为质数,$k$ 为正整数)时,不存在符合条件的 $d_1,d_2$。

充分性证明:若 $x=p^k$($p$ 为质数,$k$ 为正整数),则对于所有的 $d|x$ 且 $d≠1$,有 $p|d$。因此 $p|(d_1+d_2)$,又有 $p|x$,则 $p|\gcd(d_1+d_2,x)$,得到 $\gcd(d_1+d_2,x)\ge p>1$。因此不存在符合条件的 $d_1,d_2$。

必要性证明:若 $x$ 不是质数的正整数次幂,则对其进行质因数分解得到 $x=p_1^{a_1}\times p_2^{a_2}\times\cdots\times p_k^{a_k}$。取 $d_1=p_i^{a_i}(1\le i\le k),d_2=\frac{x}{d_1}$,则 $\gcd(d_1,d_1+d_2)=\gcd(d_2,d_1+d_2)=\gcd(d_1,d_2)=1$。因此 $\gcd(d_1+d_2,x)=\gcd(d_1+d_2,d_1d_2)=1$,$d_1,d_2$ 满足题意。

有了这样一个结论,我们就只需要线性筛一下 $2\sim10^7$ 的所有质数。线性筛能顺便计算出每个数的最小质因数,所以每次根据 $x$ 的最小质因数 $p$ 判断 $x$ 是否是 $p$ 的正整数次幂即可。

代码实现

#include<bits/stdc++.h>
using namespace std;
int n,x,ans1[500010],ans2[500010],v[10000010],p[1000010],cnt,y;//v:最小质因数,p:质数 
int main()
{
    for(int i=2;i<=10000000;i++)
    {
        if(!v[i])
            p[++cnt]=i;
        for(int j=1;j<=cnt&&i*p[j]<=10000000;j++)
        {
            v[i*p[j]]=p[j];
            if(i%p[j]==0)
                break;
        }
    }//线性筛 
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        if(!v[x])//质数没预处理质因数,特判 
            ans1[i]=ans2[i]=-1;//无解 
        else
        {
            y=v[x];
            while(y<=x/v[x]&&(x/y)%v[x]==0)//计算 p 的次数(其实可以优化,但是没必要) 
                y*=v[x];
            if(x==y)
                ans1[i]=ans2[i]=-1;//无解 
            else
                ans1[i]=y,ans2[i]=x/y;
        } 
    }
    for(int i=1;i<=n;i++)
        printf("%d ",ans1[i]);
    printf("\n");
    for(int i=1;i<=n;i++)
        printf("%d ",ans2[i]);
    return 0;
}
posted @ 2023-07-30 19:45  Hadtsti  阅读(2)  评论(0编辑  收藏  举报  来源