CodeForces 317D Game with Powers
题目描述:
有 1 到 N 共 N 个数,两个人轮流操作,每次取一个数,并且不能取以前取过的数的任意正整数次幂,第一个无法操作的人输,问谁能赢。
题解:
假设 x 不是任何其它数的正整数次幂,把 x 和它的正整数次幂分成一类,显然一个数不可能同时属于两类,于是整个游戏就被分成了若干个互不干扰的子游戏,且每个子游戏的规模不超过 log2N ,打表求出 SG 函数异或起来即可,但这样时间复杂度为 O(N) 。
然而实际上,对于超过 N−−√ 的 x ,子游戏的规模一定为 1 ,所以我们只需要统计小于等于 N−−√ 的 x 即可,时间复杂度 O(N−−√) 。
代码:
#include <set>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define MAXN 1000000007
#define MAXM 43
const int SG[] = {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, 14};
static set<int> st;
static int N, K = 0;
static bitset<MAXN> vis;
int main()
{
scanf("%d", &N);
for (int i = 2; i * i <= N; i++)
if (!vis[i])
{
int num = 0;
for (long long j = i; j <= N; j *= i, num++) st.insert(j), vis[j] = 1;
K ^= SG[num];
}
printf("%s\n", (K ^ ((N - st.size()) & 1)) ? "Vasya" : "Petya");
return 0;
}
提交记录(AC / Total = 1 / 5):
Run ID | Remote Run ID | Time(ms) | Memory(kb) | Result | Submit Time |
---|---|---|---|---|---|
8762933 | 26332213 | 60 | 124156 | WA | 2017-04-13 14:55:26 |
8763103 | 26332343 | 92 | 124152 | WA | 2017-04-13 15:06:24 |
8763245 | 26332437 | 92 | 124168 | WA | 2017-04-13 15:16:04 |
8763355 | 26332524 | 124 | 124352 | RE | 2017-04-13 15:24:27 |
8763400 | 26332547 | 124 | 126344 | AC | 2017-04-13 15:27:14 |