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;
}