其他分享
首页 > 其他分享> > 【题解】P8255 [NOI Online 2022 普及组] 数学游戏(民间数据)

【题解】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