SPOJ6059 GCDSQF Another GCD Problem 题解

题目大意

给定两个 square-free number \(A\)\(B\)(即没有一个素因子的次数达到 \(2\) 的数) 的 01 表示形式(即将其有无该素因子排列出来,如 \(105=3\times 5\times 7\),则 \(105\)01 表示形式为 0111)。求 \(\gcd(A+B,\operatorname{lcm}(A,B))\)。如果结果不是 square-free nunmber 则用十进制输出,如果结果是 \(1\) 则输出 relatively prime

分析

一道小清新的数论题。

因为 \(A\)\(B\) 是 square-free number,考虑将其唯一分解。设

\[\begin{cases}A=\prod\limits_{i=1}^np_i\\B=\prod\limits_{i=1}^mq_i\\\gcd(A,B)=\prod\limits_{i=1}^cx_i\end{cases} \]

\(\{p_i\}\)\(\{q_i\}\) 属于 \(\{x_i\}\) 的部分移动到前 \(c\) 个,那么可得:

\[\begin{cases}A+B=\prod\limits_{i=1}^cx_i(\prod\limits_{j=1}^{n-c}p_{j+c}+\prod\limits_{k=1}^{m-c}q_{k+c})\\\operatorname{lcm}(A,B)=\prod\limits_{i=1}^cx_i\prod\limits_{j=1}^{n-c}p_{j+c}\prod_{k=1}^{m-c}q_{k+c}\end{cases} \]

容易发现

\[\begin{cases}\forall p_{j+c},\ p_{j+c}\nmid\prod\limits_{j=1}^{n-c}p_{j+c}+\prod\limits_{k=1}^{m-c}q_{k+c}\\\forall q_{k+c}, \ q_{k+c}\nmid\prod\limits_{j=1}^{n-c}p_{j+c}+\prod\limits_{k=1}^{m-c}q_{k+c}\end{cases} \]

所以

\[\gcd(A+B,\operatorname{lcm}(A,B))=\gcd(A,B) \]

因此直接统计相同素因子即可。答案一定是 square-free number 或 \(1\)

实现

记得多测清空。

#include<bits/stdc++.h>
#define HohleFeuerwerke using namespace std
#pragma GCC optimize(3,"Ofast","-funroll-loops","-fdelete-null-pointer-checks")
#pragma GCC target("ssse3","sse3","sse2","sse","avx2","avx")
#define int long long
HohleFeuerwerke;
inline int read(){
	int s=0,f=1;char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	for(;isdigit(c);c=getchar()) s=s*10+c-'0';
	return s*f;
}
inline void write(int x){
	if(x<0) putchar('-'),x=-x;
	if(x>=10) write(x/10);
	putchar('0'+x%10);
}
const int MAXN=2e3+5;
int T,n,m;
char str1[MAXN],str2[MAXN];
bool A[MAXN],B[MAXN],ans[MAXN];
inline void solve(){
	memset(ans,0,sizeof(ans));
	for(int i=1;i<=max(n,m);i++){
		if(A[i]==B[i]&&A[i]==true) ans[i]=true;
		else ans[i]=false;
	}
	int len=0;
	for(int i=MAXN-5;i>=1;i--){if(ans[i]==true){len=i;break;}}
	if(len==0) puts("relatively prime");
	else{
		for(int i=1;i<=len;i++) write(ans[i]);
		puts("");
	}
}
signed main()
{
	T=read();
	while(T--){
		scanf("%s%s",str1+1,str2+1);
		memset(A,0,sizeof(A));
		memset(B,0,sizeof(B));
		n=strlen(str1+1),m=strlen(str2+1);
		for(int i=1;i<=n;i++){
			if(str1[i]=='0') A[i]=false;
			else if(str1[i]=='1') A[i]=true;
		}
		for(int i=1;i<=m;i++){
			if(str2[i]=='0') B[i]=false;
			else if(str2[i]='1') B[i]=true;
		}
		solve();
	}
	return 0;
}
posted @ 2022-10-06 21:01  _HofFen  阅读(39)  评论(0编辑  收藏  举报