题解 P1029 【最大公约数和最小公倍数问题】

小柯

2020-08-10 12:22:50

Personal

因为 $x_0=gcd(P,Q)$,故 $x_0|P,x_0|Q$。 所以设 $P=ax_0,Q=bx_0$。 假设 $a,b$ 不互质,则设 $x_1=gcd(a,b)\not=1$,则 $gcd(P,Q)=gcd(ax_0,bx_0)=x_0gcd(a,b)=x_0x_1\not=x_0$,不符合题意,故假设不成立,$a,b$ 互质。 由于 $y_0=lcm(P,Q)=lcm(ax_0,bx_0)=abx_0$,所以 $ab=\Large\frac{y_0}{x_0}$。 由于 $P=ax_0,Q=bx_0$,所以 $a,b$ 所有可能的情况与 $P,Q$ 所有可能的情况一一对应,所以只需要求出 $a,b$ 可能的情况数即可。 若 $x_0$ 不能整除 $y_0$ ,则无解,方案数为零。 若 $\frac{y_0}{x_0}=k$,将 $k$ 分解质因数得:$d_1^{c_1}\times d_2^{c_2}\times ...\times d_m^{c_m}$。 则 $ab=d_1^{c_1}\times d_2^{c_2}\times ...\times d_m^{c_m}$,由于 $a,b$ 互质,即 $a,b$没有公共的质因子。故对于每一个质因子,不管次数是多少,要么全都属于 $a$,要么全都属于 $b$。 相当于共 $m$ 个不同的物品,放入两个不同的箱子,由第二类斯特林数可以得知方案数为 $2^m-2$。 再观察样例说明可以得知还有一种特殊情况,即 $a=1$ 或 $b=1$。对于这种情况只需要在结果后面加二即可,即答案为 $2^m$ 。 综上,只需要求出 $\frac{y_0}{x_0}$ 的质因数个数 $m$ ,再求出 $2^m$ 即可。 计算质因数个个数平均时间复杂度是多少呢? ~~我也不知道~~。于是我写了个程序验证平均复杂度: ![](https://cdn.luogu.com.cn/upload/image_hosting/ur51i5go.png) 大约是 $O(69)$。 再加上快速幂的时间复杂度 $O(logm)$,而 $m\leq log{\frac{y_0}{x_0}}$,故时间复杂度约为 $O(loglog\frac{y_0}{x_0})$。 综上,时间复杂度约为 $O(69+loglog\frac{y_0}{x_0})$ (注:因为快速幂的底数为 $2$,所以对于 C++ 的 OIer 来说可以采用位运算 $O(1)$ 得到。) $Code:$ ```cpp #include<iostream> #include<cstdio> using namespace std; int x,y,cnt; int ksm(int a,int b){ int ans=1; for(;b;a*=a,b>>=1)if(b&1)ans*=a; return ans; } int main(){ scanf("%d%d",&x,&y); if(x==y)return printf("1"),0; if(y%x==0)y/=x; else return printf("0"),0; for(int i=2;i*i<=y;++i){ if(y%i==0)++cnt; while(y%i==0)y/=i; } if(y!=1)++cnt; printf("%d",ksm(2,cnt));//printf("%d",1<<cnt); return 0; } ```