【题解】P8255 [NOI Online 2022 普及组] 数学游戏(民间数据)
作者:互联网
题目传送门
题面
给你若干组 x,z ,其中\(z=x\times y\times \gcd(x,y)\) ,需要你求出最小的 y ,并支出哪些 z 有问题啊 。
其中 x,y,z 均为正整数
首先,我们假设 \(\gcd(x,y)=d\) ,则\(x=pd,y=qd,\therefore z=pd \cdot qd \cdot d=pqd^3\) 。
那么,又由 z 的式子,易知 \(y=z \div x \div d\) ,而 y 是整数,所以中间任意一次除法 有问题(指除不尽) ,你都需要判出来 -1。
接下来,就要求 d 了。
d 是什么呢?
我们考虑一个性质:这时候, p 与 q 显然是互质的,而这就意味着 \(p^2\) 与 \(q\) 也是互质的!
那我们把它们都乘上 \(d^2\) ,就会得到 \(\gcd(p^2d^2,qd^2)=d^2\) 。
而我们发现,\(x^2=p^2d^2,\frac{z}{x}=qd^2\) 。
于是,\(d^2=\gcd(x^2,\frac{z}{x})\) ,也就是说,\(d=\sqrt{\gcd(x^2,\frac{z}{x})}\)(d肯定是正整数,所以负值当然要舍去)。
那么,由于 \(z \div x \div d\) 中任意一环下来都需要是整数,而 z 和 x 一定是整数,所以 d 也需要是整数。
这要求,\(\gcd(x^2,\frac{z}{x})\) 是完全平方数。
然后随便判判,有解输出就好啦~
代码
//吾日八省吾身:
//输入多而不快读乎?
//题目标注而不freopen乎?
//乘除并列先乘后除乎?
//不手撕样例直接写代码乎?
//不仔细读题直接关页面乎?
//1e9而不开long long乎?
//Ctrl+V而不改名称乎?(papaw->papan IMPLIES tg1=->2=)
//相信评测神机乎?
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<utility>
#include<deque>
#include<ctime>
#include<sstream>
#include<list>
#include<bitset>
using namespace std;
typedef long long ll;
ll x,y,z;
ll T;
void R(ll &x){
x=0;ll f=1;char c='c';
while(c>'9'||c<'0'){
f=f*(c=='-'?-1:1);
c=getchar();
}
while(c<='9'&&c>='0'){
x=x*10+c-'0';
c=getchar();
}
x=x*f;
return;
}
ll gcd(ll a,ll b){
if(a%b==0) return b;
else return gcd(b,a%b);
}
int main(){
R(T);
while(T--){
R(x);R(z);
if(z%x!=0){
cout<<"-1"<<endl;
continue;
}
ll fa=gcd(x*x,z/x);
ll sq=sqrt(fa);
if((sq*sq!=fa)||((z/x)%sq!=0)){
cout<<"-1"<<endl;
continue;
}
cout<<z/x/sq<<endl;
}
return 0;
}
标签:gcd,题解,ll,long,P8255,qd,div,include,NOI 来源: https://www.cnblogs.com/Konjac-Binaries/p/16074813.html