zoukankan      html  css  js  c++  java
  • 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
    ");
    84   else printf("Mojtaba
    ");
    85 }
  • 相关阅读:
    SQL Sever语言 存储过程及触发器
    计蒜客 挑战难题 移除数组中的重复元素
    projecteuler Sum square difference
    码农谷 求前N项之和
    projecteuler Smallest multiple
    计蒜客 挑战难题 寻找插入位置
    Largest palindrome product
    计蒜客 挑战难题 元素移除
    码农谷 球从M米高度自由下落第N次落地时反弹的高度
    挑战难题 奇怪的国家
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8570237.html
Copyright © 2011-2022 走看看