Topic Link: Portal
Game rules:
No time can be divided into two piles x = A*b (a!=1&&b!=1) x is the number of the original heap, A, B is the number of the new heap.
It is also possible to change the number of the original heap to the approximate y of the original heap. Y!=x. The person who made the last operation wins.
Analysis:
It's also a stone-going game, so we just need to make the whole SG value different or better.
Let's consider a bunch of them first. Set the number of this heap is x;
So the whole situation is
( a1,x/a1), (A2,X/A2),..., (an,x/an); or (A1), (A2),.., (AN).
Due to the large amount of data, we will definitely time out the modest number of approximations.
Then analyze the problem in detail. Because I
They are all surrounded by an approximate operation. Then it would be equivalent to manipulating the number of his factors.
X=a1^r1*a2^r2*...*an^rn; Set sum = R1+r2+...+rn.
Then the whole situation can be expressed as:
(1,sum-1), (2,sum-2),... (SUM/2,SUM-SUM/2) or (1),(2),... (n-1)
This greatly reduces the scope of the data. Then we can calculate the sum in this way.
set a number to X, and his smallest element factor is Y. sum[x] = sum[x/y] + 1;
The code is as follows:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm>using namespace std;const int maxn = 5000010;int prime[maxn],cnt;bool isprime[maxn];int fac_num[maxn];int min_fac[maxn];int sg[100]; void Getpirme () {cnt=0; memset (isprime,0,sizeof (IsPrime)); memset (fac_num,-1,sizeof (fac_num)); memset (min_fac,-1,sizeof (MIN_FAC)); for (int i=2;i<maxn;i++) {if (!isprime[i]) {prime[cnt++]=i; for (int j=i+i;j<maxn;j+=i) {isprime[j]=1; if (min_fac[j]==-1) min_fac[j]=i; } min_fac[i]=i; }}}int get_num (int x) {if (x==1) return 0; if (fac_num[x]!=-1) return fac_num[x]; Return Fac_num[x]=get_num (x/min_fac[x]) +1;} int get_sg (int x) {if (sg[x]!=-1) return sg[x]; BOOL vis[100]; memset (vis,0,sizeof (VIS)); for (int i=1;i<=x;i++) VIS[GET_SG (x-i)]=1; for (int i=1;i<=x/2;i++) VIS[GET_SG (i) ^get_sg (x-i)]=1; for (int i=0;; i++) {if (!vis[i]) {return sg[x]=i; }}}void init () {getpirme (); memset (sg,-1,sizeof (SG)); sg[0]=0;} int main () {init (); int n; while (~SCANF ("%d", &n)) {int x, ans=0; for (int i=0;i<n;i++) {scanf ("%d", &x); cout<< "num:" <<get_num (x) <<endl; Ans^=get_sg (Get_num (x)); } if (ans) puts ("Alice"); Else puts ("Bob"); } return 0;}
Acdream 1112 Alice and Bob (game && Prime number screening optimization)