Codeforces 151C Win or Freeze 简单博弈+唯一分解

来源:互联网 发布:法里内利 知乎 编辑:程序博客网 时间:2024/05/17 04:38

点击打开链接

题意:给出一个数字n,n<=1e13,操作:将n变为n的某个因子(因子不包括1,n),两个聪明的玩家轮流操作,不能操作的人胜利,问1先手,是否能赢,若能则输出第一步操作
一个状态为1或者素数则为必胜,一个结点n的后继为:n的因子 
若后继(因子)都为必胜态(素数)则必败
首先n用唯一分解表示为n=p1^a1 *p2^a2*...pn^an,若存在一个因子不为素数,则i>=2或者i==1&&ai>=2
若i==1&&ai>=2 则取n的一个因子 p1^2 则为必胜态
若i>=2 则取p1*p2 则也为必胜态

即存在一个因子不为素数的状态为必胜态

#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N=2e7+20;const ll M=1e13;ll n,q;ll pri[N],pn=0;int vis[N];void init()//找到sqrt(M)内所有的素数 {memset(vis,-1,sizeof(vis));for(ll i=2;i*i<=M;i++){if(vis[i]==-1){pri[pn++]=i;vis[i]=1;for(ll j=i+i;j*j<=M;j+=i)vis[j]=1;}}}ll solve(){ll ans=-1;ll num=0,a;//有因子为合数则:找到两个素因子a,b.或者一个素因子的平方 for(int i=0;i<pn;i++){if(n%pri[i]==0){int cnt=0;num++;if(num==1)a=pri[i];if(num==2){ans=a*pri[i];return ans;}while(n%pri[i]==0){n/=pri[i];cnt++;if(cnt==2){ans=pri[i]*pri[i];return ans;} } }}return -1;}int main(){init();while(cin>>n){q=n;bool flag=false;int num=0; for(ll i=2;i*i<=n;i++){if(n%i==0){num++;break;}}if(num==0)//n为prime||1 {cout<<1<<endl<<0<<endl;continue;}ll ans=solve();if(ans==-1||ans==q)puts("2");else{puts("1");cout<<ans<<endl;}}return 0;} 


 

0 0
原创粉丝点击