D. Game with Powers
Vasya and Petya wrote down all integers from 1 to n to play the "powers" game (n can be quite large; however, Vasya and Petya are not confused by this fact).
Players choose numbers in turn (Vasya chooses first). If some number x is chosen at the current turn, it is forbidden to choose x or all of its other positive integer powers (that is, x2, x3, ...) at the next turns. For instance, if the number 9 is chosen at the first turn, one cannot choose 9 or 81 later, while it is still allowed to choose 3 or 27. The one who cannot make a move loses.
Who wins if both Vasya and Petya play optimally?
Input contains single integer n (1 ≤ n ≤ 109).
Print the name of the winner — "Vasya" or "Petya" (without quotes).
1
Vasya
2
Petya
8
Petya
In the first sample Vasya will choose 1 and win immediately.
In the second sample no matter which number Vasya chooses during his first turn, Petya can choose the remaining number and win.
我感觉这个问题,要是深入的了解了SG函数做这个题是很轻松的,但是我菜啊,so只能先把别人的代码看懂了,但是真的感觉这个问题是SG函数的经典的问题。因为要是把SG函数写在里面真的是时间爆炸啊,因为集合中最多才可能是29个,所以直接打表然后就OK了
#include<bits/stdc++.h> using namespace std; long long cnt; int vis[200000]; map<long long,long long>f; /*int SG(long long r) { int vis[40]; memset(vis,0,sizeof(vis)); if(f[r]) return f[r]; if(r==0) return 0; for(int i=1;i<=30;i++) { if(r&(1<<(i-1))) { long long tem=r; for(int j=i;j<=30;j+=i) { cnt++; if(tem&(1<<(j-1))) tem^=(1<<(j-1)); } vis[SG(tem)]=1; } } for(int i=0;;i++) { if(vis[i]==0) { f[r]=i; return i; } } }*/ int main() { int sg[30]={0, 1, 2, 1, 4, 3, 2, 1, 5, 6, 2, 1, 8, 7, 5, 9, 8, 7, 3, 4, 7, 4, 2, 1, 10, 9, 3, 6, 11, 12}; int n; scanf("%d",&n); int k; for(k=1;;k++) { if(k*k>=n) break; } f[1]=1; long long sum=0; long long ans=0; for(int i=2;i<=k;i++) { int cnt=0; long long temp=i; if(vis[temp]) continue; while(temp<=n) { cnt++; if(temp<=k) vis[temp]=1; if(temp>k) sum++; temp*=i; } f[cnt]++; } f[1]+=n-k-sum; for(int i=1;i<=30;i++) { if(f[i]&1) ans^=sg[i]; } if(ans) printf("Vasya"); else printf("Petya"); }