Codefroces 850C Arpa and a game with Mojtaba

Description
两个人Van♂游戏。给出$n$个正整数$ai$两人轮流操作,每次选出一个素数$p$和一个幂数$k$,选择的前提为该$n$个数中有$p^{k}$的倍数。接着将所有的$p^{k}$的倍数除以$p^{k}$。变成新的序列,继续操作。不能操作者为败,问先手是否必胜。
1≤100≤n,1≤ai≤109
Examples
Input
4
1 1 1 1
Output
Arpa

Input
4
1 1 17 17
Output
Mojtaba

Input
4
1 1 17 289
Output
Arpa

Input
5
1 2 3 4 5
Output
Arpa

不同质因数不互相影响

于是分开讨论每个质因数的SG值

压缩状态,如果一个数含有k个p

即$a[i]%p^{k}==0$

那么状态中第k-1位为1

那么枚举每一次的k,求出SG值

最后将每个质因数的答案取Nim和

不过状态可能会很大,用map

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<map>
 7 using namespace std;
 8 map<int,int>sg;
 9 int n,a[101],pri[100001],Max[100001],cnt,ans;
10 map<int,int>vis;
11 int qpow(int x,int y)
12 {
13   int res=1;
14   while (y)
15     {
16       if (y&1) res=res*x;
17       x=x*x;
18       y>>=1;
19     }
20   return res;
21 }
22 int get_SG(int S)
23 {int i,p,SS,t;
24   if (sg.count(S)) return sg[S];
25   if (S==0) return 0;
26   map<int,int>v;
27   t=0;SS=S;
28   while (SS)
29     {
30       SS>>=1;
31       t++;
32     }
33   for (i=0;i<t;i++)
34     {
35       p=i+1,SS=S;
36       v[get_SG((SS>>p)|(((1<<p-1)-1)&S))]=1;
37     }
38   for (p=0;;p++)
39     if (v.count(p)==0) break;
40   return sg[S]=p;
41 }
42 int main()
43 {int i,j,tot,k;
44   cin>>n;
45   for (i=1;i<=n;i++)
46     {
47       scanf("%d",&a[i]);
48       int x=a[i],k=sqrt(x);
49       for (j=2;j<=k;j++)
50     {tot=0;
51       while (x%j==0)
52         {
53           tot++;
54           if (vis[j]==0) pri[++cnt]=j,vis[j]=cnt;
55           x/=j;
56         }
57       Max[vis[j]]=max(tot,Max[vis[j]]);
58     }
59       if (x!=1)
60     {
61       if (vis[x]==0) pri[++cnt]=x,vis[x]=cnt;
62       Max[vis[x]]=max(Max[vis[x]],1);
63     }
64     }
65   ans=0;
66   for (i=1;i<=cnt;i++)
67     {
68       sg.clear();
69       int S=0;
70       for (j=1;j<=n;j++)
71     {
72       for (k=Max[i];k>=1;k--)
73         {
74           if (a[j]%qpow(pri[i],k)==0)
75         {
76           S|=(1<<k-1);
77           break;
78         }
79         }
80     }    
81       ans^=get_SG(S);
82     }
83   if (ans==0) printf("Arpa\n");
84   else printf("Mojtaba\n");
85 }

 

posted @ 2018-03-14 21:24  Z-Y-Y-S  阅读(148)  评论(0编辑  收藏  举报