CF 1445C

題目傳送門

題目大意是,給定\(p_i\)\(q_i\),找到一個最大的\(x_i\)使得\(p_i \mod x_i=0\)\(x_i \mod q_i \neq 0\)

分情況討論:

1.\(p_i < q_i\)時,答案爲\(p_i\).

2.\(p_i \mod q_i \neq 0\)時,答案爲\(p_i\).

3.利用唯一分解定理分解\(p_i\)\(q_i\):

\(p_i = k_1^{t_1} * k_2^{t_2} * k_3^{t_3} * ... * k_n^{t_n}\)

\(p_i = k_1^{r_1} * k_2^{r_2} * k_3^{r_3} * ... * k_n^{r_n}\)

其中,\(\forall r_i,t_i\)都滿足\(t_i \geq r_i\)

而要找的\(x\),滿足\(x = k_1^{d_1} * k_2^{d_2} * k_3^{d_3} * ... * k_n^{d_n}\)\(\exists i\) 使得\(d_i < t_i\)\(d_i \geq 0\).

所以最終要做的就是枚舉\(q_i\)的所有質因子,使其次數減一,其它所有質因子次數與\(p_i\)裏的一樣(包括\(q_i\)不含的質因子).

注意:對於第三種情況,\(q_i\)可能是一個大質數,導致我們無法枚舉到那個質因子,所以答案爲\(p_i\)除去所有\(p_i\)後的餘數.

下面給兩份代碼(一份Wa,一份AC),WA的原因是運用錯誤處理方法,使得對於一些因數爲大質數的數分解錯誤.

//AC
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>

using namespace std;

long long t,tot,zs;
long long num[1000001],sum[1000001];
long long x,y,ans,mx;
bool vis[1000001];

inline void oula() {
	vis[1] = 1;
	for(long long i = 2;i <= 1000000; i++) {
		if(!vis[i]) num[++tot] = i;
		for(long long j = 1;j <= tot; j++) {
			if(num[j] * i > 1000000) break;
			vis[num[j]*i] = 1;
			if(i % num[j] == 0) break;
		}
	}
}

inline void fenjie(long long a) {
	for(long long i = tot;i >= 1; i--) {
		while(a % num[i] == 0) {
			sum[i]++;
			a = a / num[i];
		}
	}
}

int main() {
	scanf("%lld",&t);
	oula();
	while(t--) {
		memset(sum,0,sizeof(sum));
		ans = 1;
		scanf("%lld%lld",&x,&y);
		if(x < y) {
			printf("%lld\n",x);
			continue;
		}
		if(x % y != 0) {
			printf("%lld\n",x);
			continue;
		}
		fenjie(y);
		for(long long i = tot;i >= 1; i--) {
			if(sum[i] == 0) continue;
			long long uu = x,vv = y,m1 = 0,m2 = 0;
			while(uu % num[i] == 0) uu /= num[i],m1++;
			while(vv % num[i] == 0) vv /= num[i],m2++;
			for(int j = 1;j <= m2 - 1; j++) uu *= num[i];
			ans = max(ans,uu);
		}
		if(ans == 1) {
			while(x % y == 0) x /= y;
			ans = x;
		}
		printf("%lld\n",ans);
	}
	return 0;
} 
//WA
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>

using namespace std;

long long t,tot,zs;
long long num[1000001],sum[1000001];
long long x,y,ans,mx;
bool vis[1000001];

inline void oula() {
	vis[1] = 1;
	for(long long i = 2;i <= 1000000; i++) {
		if(!vis[i]) num[++tot] = i;
		for(long long j = 1;j <= tot; j++) {
			if(num[j] * i > 1000000) break;
			vis[num[j]*i] = 1;
			if(i % num[j] == 0) break;
		}
	}
}

inline void fenjie(long long a) {
	for(long long i = tot;i >= 1; i--) {
		while(a % num[i] == 0) {
			zs++;
			sum[i]++;
			a = a / num[i];
		}
	}
}

int main() {
	scanf("%lld",&t);
	oula();
	while(t--) {
		zs = 0;
		memset(sum,0,sizeof(sum));
		ans = 1;
		scanf("%lld%lld",&x,&y);
		if(x < y) {
			printf("%lld\n",x);
			continue;
		}
		if(x % y != 0) {
			printf("%lld\n",x);
			continue;
		}
		fenjie(y);
		for(long long i = tot;i >= 1; i--) {
			if(sum[i] == 0) continue;
			long long uu = y / num[i];
			long long vv = x / y;
			while(vv % num[i] == 0) vv = vv / num[i];
			ans = max(ans,vv * uu);
		}
		if(zs <= 1) {
			while(x % y == 0) x /= y;
			ans = x;
		}
		printf("%lld\n",ans);
	}
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章