1. 程式人生 > >[CodeForces850C]Arpa and a game with Mojtaba

[CodeForces850C]Arpa and a game with Mojtaba

sqrt 作者 div 位數 line 為我 hash_map 整數 所有

題目大意:
  給你一個包含n個數的數列,兩個人輪流對數列進行如下操作:
  選擇一個質數p和一個正整數k,將數列中所有能被p^k整除的數除以p^k。
  最後不能操作者負。
  問先手是否有必勝策略。

思路:
  顯然,結果不直接與數列中數的值有關,而與數列中每個數的質因數及其次數有關,因此我們可以將每個質因數分開考慮。
  枚舉數列中出現的每一個質因數p,對數列中的數除去p^k就相當於將p對應的次數減去k。
  如果不同的數對於同一個質因數p,對應的次數相同,那麽無論除去p的幾次,對於這兩個數的影響都是一樣的。
  那麽我們只需要將不同的質數作為我們的子遊戲,遊戲狀態記錄p出現次數(即,如果一個數中包含17,一個數中包含17^2,那麽就記錄1和2)。

  極限情況,2^31>1e9,那麽對於每一個質數,我們可以用一個int類型狀壓記錄出現次數。
  即,若狀態s的第i位為1,則p^i在數列中出現。
  求SG函數的時候,我們可以發現SG函數的取值僅與出現次數,即狀態s有關,而與具體是哪個質數無關。
  我們可以從s的最高位枚舉,依次考慮把s在i後面的位數減掉的情況,這樣,較高的次數在降次以後會加到較低的位數,這一操作可以用位運算(x%si)|(x/si)表示。
  對於邊界情況,s=1時,表示數列中已經沒有這樣的質因數,SG值顯然是0。

 1 #include<cmath>
 2 #include<cstdio>
 3
#include<cctype> 4 #include<vector> 5 #include<cstring> 6 #include<ext/hash_map> 7 inline int getint() { 8 register char ch; 9 while(!isdigit(ch=getchar())); 10 register int x=ch^0; 11 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^
0); 12 return x; 13 } 14 const int N=100; 15 __gnu_cxx::hash_map<int,int> sg; 16 int a[N]; 17 inline int count(int &x,const int &p) { 18 int ret=0; 19 while(!(x%p)) { 20 ret++; 21 x/=p; 22 } 23 return ret; 24 } 25 int getsg(const int x) { 26 if(sg.count(x)) { 27 return sg[x]; 28 } 29 if(x==1) return sg[x]=0; 30 int si=1<<30; 31 while(!(x&si)) si>>=1; 32 int mex[10000]; 33 memset(mex,0,sizeof mex); 34 while(si!=1) { 35 mex[getsg((x%si)|(x/si))]=x; 36 si>>=1; 37 } 38 int tmp=0; 39 while(mex[tmp]==x) tmp++; 40 return sg[x]=tmp; 41 } 42 int main() { 43 int n=getint(); 44 for(int i=0;i<n;i++) { 45 a[i]=getint(); 46 } 47 int ans=0; 48 for(int i=0;i<n;i++) { 49 int tmp=a[i]; 50 for(int j=2;j<=sqrt(tmp);j++) { 51 if(!(tmp%j)) { 52 int s=0; 53 for(int k=0;k<n;k++) { 54 s|=1<<count(a[k],j); 55 } 56 ans^=getsg(s); 57 } 58 } 59 if(a[i]!=1) { 60 int p=a[i]; 61 int s=0; 62 for(int k=0;k<n;k++) { 63 s|=1<<count(a[k],p); 64 } 65 ans^=getsg(s); 66 } 67 } 68 puts(ans?"Mojtaba":"Arpa"); 69 return 0; 70 }

[CodeForces850C]Arpa and a game with Mojtaba