Luogu P5316 【恋恋的数学题】

是个神仙

就三种情况,分类讨论。

\(k=2\)

因为保证有解,所以直接输出即可。

\(k=3\)

由于对应情况可以枚举全排列寻找,所以在此只考虑顺序对应时的情况,不妨设六个数分别为\(g_{ab},g_{ac},g_{bc},l_{ab},l_{ac},l_{bc}\),由小学数学知识可知\(g_{ab}l_{ab}=ab,g_{ac}l_{ac}=ac,g_{bc}l_{bc}=bc\),又\(\large\frac{ab\cdot ac}{bc}\normalsize=a^2\),所以\(a=\sqrt{\large\frac{ab\cdot ac}{bc}}\),同理\(b=\sqrt{\large\frac{ab\cdot bc}{ac}},c=\sqrt{\large\frac{ac\cdot bc}{ab}}\)。需要注意的是直接算\(ab\cdot ac\)会爆__int128,在此改为计算\(\Large\frac{ab}{\gcd(ab,bc)}\cdot\frac{ac}{\frac{bc}{\gcd(ab,bc)}}\)

\(k=4\)

\(k=3\),不妨设所有数分别为\(g_{ab},g_{ac},g_{bc},g_{ad},g_{bd},g_{cd},l_{ab},l_{ac},l_{bc},l_{ad},l_{bd},l_{cd}\),由于已知\(k=3\)的解法,分别求\(a,b,c\)\(a,b,d\)即可,最后合并答案。

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef __int128 LLL;

LLL gcd(LLL u,LLL v){
	if(v==0){
		return u;
	}
	return gcd(v,u%v);
}

LLL lcm(LLL u,LLL v){
	return u/gcd(u,v)*v;
}

LLL sqrt(LLL u){
	LLL mid,l=1,r=1e18;
	while(l<=r){
		mid=(l+r)>>1;
		if(mid*mid==u){
			return mid;
		}
		else if(mid*mid<u){
			l=mid+1;
		}
		else{
			r=mid-1;
		}
	}
	return 0;
}

LLL div(LLL a,LLL b,LLL c){
	LLL _g=gcd(a,c);
	c/=_g;
	return (a/_g)*(b/c);
}

int t,k,n;

LL g[10],l[10],ans[10];

vector<LL>solve3(LLL g12,LLL g13,LLL g23,LLL l12,LLL l13,LLL l23){
	LLL ans1,ans2,ans3,x12,x13,x23;
	x12=g12*l12;
	x13=g13*l13;
	x23=g23*l23;
	ans1=sqrt(div(x12,x13,x23));
	ans2=sqrt(div(x12,x23,x13));
	ans3=sqrt(div(x23,x13,x12));
	if(ans1*ans2*ans3==0){
		return {};
	}
	if(gcd(ans1,ans2)==g12&&lcm(ans1,ans2)==l12&&
	gcd(ans2,ans3)==g23&&lcm(ans2,ans3)==l23&&
	gcd(ans1,ans3)==g13&&lcm(ans1,ans3)==l13){
		return {(LL)ans1,(LL)ans2,(LL)ans3};
	}
	else{
		return {};
	}
}

void solve(){
	if(k==2){
		ans[1]=g[1];ans[2]=l[1];
	}
	else if(k==3){
		for(int i=6;i;i--,next_permutation(g+1,g+4)){
			for(int j=6;j;j--,next_permutation(l+1,l+4)){
				auto rep=solve3(g[1],g[2],g[3],l[1],l[2],l[3]);
				if(rep.empty()){
					continue;
				}
				ans[1]=rep[0];ans[2]=rep[1];ans[3]=rep[2];
				return;
			}
		}
	}
	else{
		for(int i=720;i;i--,next_permutation(g+1,g+7)){
			for(int j=720;j;j--,next_permutation(l+1,l+7)){
				auto rep1=solve3(g[1],g[2],g[3],l[1],l[2],l[3]),rep2=solve3(g[1],g[4],g[5],l[1],l[4],l[5]);
				if(rep1.empty()||rep2.empty()){
					continue;
				}
				if(rep1[0]!=rep2[0]||rep1[1]!=rep2[1]){
					continue;
				}
				if(gcd(rep1[2],rep2[2])!=g[6]||lcm(rep1[2],rep2[2])!=l[6]){
					continue;
				}
				ans[1]=rep1[0];ans[2]=rep1[1];ans[3]=rep1[2];ans[4]=rep2[2];
				return;
			}
		}
	}
}

int main(){
	scanf("%d%d",&t,&k);
	n=(k-1)*k/2;
	while(t--){
		for(int i=1;i<=n;i++){
			scanf("%lld",&g[i]);
		}
		for(int i=1;i<=n;i++){
			scanf("%lld",&l[i]);
		}
		solve();
		for(int i=1;i<=k;i++){
			printf("%lld%c",ans[i]," \n"[i==k]);
		}
	}
	return 0;
}
posted @ 2019-04-23 10:38  __BLUESKY007  阅读(328)  评论(0编辑  收藏  举报