Win or Freeze CodeForces - 150A

原题链接
考察:数论
思路:
  如果先手胜,说明\(n\)是一个质数或者\(n\)存在因子,该因子只有质因数.第二个条件判断只需要\(n\)有两个质因子,而不需要一个个枚举因数.

Code

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
typedef long long LL;
const int N = 1e7+4000;
int prime[N],cnt;
bool st[N];
LL n;
vector<LL> di;
void GetPrime(int n)
{
	st[1] = st[0] =1;
	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;
		}
	}
}
bool check(LL n)
{
	if(n==1) return 1;
	for(int i=2;i<=n/i;i++)
		if(n%i==0) return 0;
	return 1;
}
void GetDivide(LL n)
{
	for(int i=2;i<=n/i;i++)
	{
		if(n%i==0)
		{
			di.push_back(i);
			if(n%i==0) di.push_back(n/i);
		}
	}
}
void solve()
{
	for(int i=0;i<di.size();i++)
	{
		LL x = di[i];
		if(x%2==0&&x!=2)
		{
			x/=2;
			if(x%2==0&&x>2) continue;
			if(check(x)) {printf("1\n%lld\n",x*2);return;}
			continue;
		}else{
			if(x>=N&&check(x)) continue;
			else if(x<N&&!st[x]) continue;
			int v = sqrt(x);//x是否能被两个质数的乘积表示
			int r = lower_bound(prime+1,prime+cnt+1,v)-prime;
			for(int j=r;j>=1;j--)
			  if(x%prime[j]==0)
			  {
			  	if(x/prime[j]<N&&st[x/prime[j]]) continue;
			  	if(x/prime[j]>=N&&!check(x/prime[j])) continue;
			  	printf("1\n%lld\n",x);
			  	return;
			  }
		}
	}
	printf("2\n");
}
int main()
{
	scanf("%lld",&n);
	GetPrime(N-1);
	if(check(n)) printf("1\n0\n");
	else{
		GetDivide(n);
		solve();
	}
	return 0;
}
posted @ 2021-07-27 08:27  acmloser  阅读(33)  评论(0编辑  收藏  举报