Codeforces Round #725 (Div. 3)

比赛链接

Codeforces Round #725 (Div. 3)

D. Another Problem About Dividing Numbers

给定两个整数 \(a, b\) 和一个操作数 \(k\) 。对于每一次操作,你有如下两种选择:

  • 选择一个能整除 \(a\) 的大于一的整数 \(c\) ,用 \(\frac{a} { c }\) 替换a 。
  • 选择一个能整除 \(b\) 的大于一的整数 \(c\) ,用 \(\frac{b}{c}\) 替换 \(b\)

然后询问,是否存在一种操作方法,使得在恰好 \(k\) 次操作后, \(a=b\)
数据范围: \(1<a, b, k<10^{9}\)

解题思路

质因数分解

先求出 \(a\)\(b\) 的质因子总数 \(s\)\(k>s\) 显然是不合要求的,而 \(k\leq s\) 时需要分情况考虑,先特判 \(k=1\) 的情况,而如果 \(k=2\),且仍有 \(k\leq s\) 的情况,则可使 \(a=b=1\) 满足条件,可以发现:只要 \(k\leq s\),最后一定可以使 \(a=b=1\),所以关键在于求出质因子个数,但每次直接分解需要 \(O(\sqrt{10^9})\) 的复杂度,太高,可以考虑先线性筛出 \(1\sim \sqrt{10^9}\) 内的质数,这样的数有 \(3401\) 个,再拿这些质数分解,同时可以记忆化数的质因数个数

  • 时间复杂度:\(O(3401\times t)\)

代码

// Problem: D. Another Problem About Dividing Numbers
// Contest: Codeforces - Codeforces Round #725 (Div. 3)
// URL: https://codeforces.com/contest/1538/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=1e5+5;
int prime[N],v[N],m,t,a,b,k;
unordered_map<int,int> f;
void primes(int n)
{
	for(int i=2;i<=n;i++)
	{
		if(v[i]==0)
		{
			prime[++m]=i;
			v[i]=i;
		}
		for(int j=1;j<=m;j++)
		{
			if(i*prime[j]>=N||v[i]<prime[j])break;
			v[i*prime[j]]=prime[j];
		}
	}	
}
int main()
{
	help;
    primes(sqrt(1e9));
    for(cin>>t;t;t--)
    {
    	cin>>a>>b>>k;
    	if(k==1)
    	{
    		if(a<b)swap(a,b);
    		puts(a%b==0&&a/b>1?"YES":"NO");
    		continue;
    	}
    	int res=0,ta=a,tb=b,cnta=f[a],cntb=f[b];
    	if(cnta==0)
    	{
    		for(int i=1;i<=m&&prime[i]<=a;i++)
    			while(a%prime[i]==0)
    			{
    				cnta++,a/=prime[i];
    				if(f[a])
    				{
    					cnta+=f[a];
    					a=0;
    					break;
    				}
    			}
    		if(a>1)cnta++;
    	}
    	f[ta]=cnta;
    	if(cntb==0)
    	{
    		for(int i=1;i<=m&&prime[i]<=b;i++)
    			while(b%prime[i]==0)
    			{
    				cntb++,b/=prime[i];
    				if(f[b])
    				{
    					cntb+=f[b];
    					b=0;
    					break;
    				}
    			}
    		if(b>1)cntb++;
    	}
    	f[tb]=cntb;
    	puts(f[ta]+f[tb]>=k?"YES":"NO");
    }
    return 0;
}
posted @ 2022-05-23 00:18  zyy2001  阅读(19)  评论(0编辑  收藏  举报