CF1647D (Round #777) 题解 数论
前言:分讨题爬
题意:
给定 \(x,d(2\le x,d\le 10^9)\),定义 \(d\) 的倍数为“好数”,不能分解为好数之积的好数为“漂亮数”。
保证 \(x\) 是好数,询问 \(x\) 是否有两种方式分解为漂亮数之积。多组询问。
(注:本文中“分解”和“拆”均指分解为积)
首先,令 \(x=d^k\times s\),其中 \(k>0,d\nmid s\)。
那么 \(k-1\) 个 \(d\) 和一个 \(d\times s\) 即为一种分解方案。
接下来考虑构造另一种。
- 若 \(k=1\),则显然没有第二种方案。
则接下来的讨论中均有 \(k>1\)。
- 若 \(s\) 为合数,则将其分解为两个数,分别乘在两个 \(d\) 上,则得到第二种方案。
则接下来的讨论中 \(s\) 均为质数或 \(1\)。
那么 \(s\) 拆不动了,只能拆 \(d\)。
- 若 \(d\) 为质数,那么它就没得拆,所以没有第二种方案。
则现在剩下的情况是 \(k>1\),\(s\) 不是合数,\(d\) 是合数。
- 若 \(d\) 中含有不同于 \(s\) 的质因数,则将这个质因数乘在一个 \(d\) 上,剩下的部分与 \(s\) 一起乘在另一个 \(d\) 上,则得到第二种方案,连上被拆的一共需要 \(3\) 个 \(d\),所以需要 \(k>2\)。
那么注意到,接下来的讨论中有 \(d=s^q\),其中 \(q>1\)。
-
若 \(q>2\),则 \(d\) 可以拆为 \(s\) 和 \(s^{q-1}\)。将 \(s^2\) 和 \(s^{q-1}\) 分别乘在一个 \(d\) 上,则得到第二种方案,连上被拆的一共需要 \(3\) 个 \(d\),所以需要 \(k>2\)。
-
若 \(q=2\),则 \(d\) 可以拆为两个 \(s\)。现在不能将 \(s^2\) 乘在 \(d\) 上了(因为结果不是漂亮数),所以只能将三个 \(s\) 分别乘在三个 \(d\) 上,连上被拆的一共需要 \(4\) 个 \(d\),所以需要 \(k>3\)。
注意到后三类可以整合为对 \(s^2\) 与 \(d\) 是否相等的判断。
分类清楚了,代码就容易实现了。加一个质数判断即可。时间复杂度 \(O(T\sqrt{x})\)。
code
#include<cstdio>
using namespace std;
int T,x,d,k;
bool check(int n){
if(n<4) return 1;
if(n%2==0||n%3==0) return 0;
for(int i=5;i*i<=n;i+=6)
if(n%i==0||n%(i+2)==0) return 0;
return 1;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&x,&d);
for(k=0;x%d==0;x/=d,++k);
if(k<2) printf("NO\n");
else if(!check(x)) printf("YES\n");
else if(check(d)) printf("NO\n");
else printf(k>(x*x==d)+2?"YES\n":"NO\n");
}
return 0;
}

浙公网安备 33010602011771号