Reducing Fractions CodeForces - 222C

原题链接
考察:质因数分解,筛质数
思路:
??比较明显的思路是循环\(1\)~\(n\)每一个\(a[i]\),分解质因数,时间复杂度约为n*\(\sqrt{10^7}\)会有超时的风险.
??优化就是筛到\(10^7\)的质数,然后判断为质数立马跳出.
??将质数的指数取最小值.然后循环\(a[i],b[i]\)除去质数.
??但是这里不适合指数取原值\(-\)最小值,因为求积时会爆long long.

Code

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
typedef long long LL;
const int N = 1e7+10,M = 100010;
int n,m,prime[N],cnt,a[M],b[M];
int pa[N],pb[N];
bool st[N];
void GetPrime(int n)
{
	for(int i=2;i<=n;i++)
	{
		if(!st[i]) prime[++cnt] = i;
		for(int j=1;prime[j]<=n/i;j++)
		{
			st[i*prime[j]] = 1;
			if(i%prime[j]==0) break;
		}
	}
}
void div(int s,int ps[])
{
	for(int i=1;prime[i]<=s/prime[i]&&st[s];i++)
	{
		if(s%prime[i]==0)
		{
			int sz = 0;
			while(s%prime[i]==0) s/=prime[i],ps[prime[i]]++;
		}
	}
	if(s>1) ps[s]++;
}
LL qsm(int a,int k)
{
	LL res = 1;
	while(k)
	{
		if(k&1) res = (LL)a*res;
		a = (LL)a*a;
		k>>=1;
	}
	return res;
}
void reduce(int& x,int ps[])
{
	int res = x;
	for(int i=1;prime[i]<=x/prime[i];i++)
	{
		if(!st[x]) break;
		if(x%prime[i]==0)
		{
			while(x%prime[i]==0)
			{
				x/=prime[i];
				if(ps[prime[i]]) ps[prime[i]]--,res/=prime[i];
			}
		}
	}
	if(x>1&&ps[x]) ps[x]--,res/=x,x = 1;
	x = res;
}
int main()
{
	scanf("%d%d",&n,&m);
	GetPrime(N-1);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		div(a[i],pa);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&b[i]);
		div(b[i],pb);
	}
	for(int i=1;i<=cnt;i++)
	{
		int ca = pa[prime[i]],cb = pb[prime[i]];
		pa[prime[i]]=min(ca,cb);
		pb[prime[i]]=min(ca,cb);
	}
	for(int i=1;i<=n;i++) reduce(a[i],pa);
	for(int i=1;i<=m;i++) reduce(b[i],pb);
	printf("%d %d\n",n,m);
	for(int i=1;i<=n;i++) printf("%d ",a[i]);
	printf("\n");
	for(int i=1;i<=m;i++) printf("%d ",b[i]);
	printf("\n");
	return 0;
}

Reducing Fractions CodeForces - 222C

上一篇:容器Docker进入的四种方法


下一篇:华为云严选上新啦!高效准确的数据同步方案来了