codefoeces 603C (博弈 SG函数找规律)

C. Lieges of Legendre
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Kevin and Nicky Sun have invented a new game called Lieges of Legendre. In this game, two players take turns modifying the game state with Kevin moving first. Initially, the game is set up so that there are n piles of cows, with the i-th pile containing ai cows. During each player's turn, that player calls upon the power of Sunlight, and uses it to either:

  1. Remove a single cow from a chosen non-empty pile.
  2. Choose a pile of cows with even size x (x > 0), and replace it with k piles of x cows each.

The player who removes the last cow wins. Given nk, and a sequence a1, a2, ..., an, help Kevin and Nicky find the winner, given that both sides play in optimal way.

Input

The first line of the input contains two space-separated integers n and k (1 ≤ n ≤ 100 000, 1 ≤ k ≤ 109).

The second line contains n integers, a1, a2, ... an (1 ≤ ai ≤ 109) describing the initial state of the game.

Output

Output the name of the winning player, either "Kevin" or "Nicky" (without quotes).

Sample test(s)
input
2 1
3 4
output
Kevin
input
1 2
3
output
Nicky
Note

In the second sample, Nicky can win in the following way: Kevin moves first and is forced to remove a cow, so the pile contains two cows after his move. Next, Nicky replaces this pile of size 2 with two piles of size 1. So the game state is now two piles of size 1. Kevin then removes one of the remaining cows and Nicky wins by removing the other.


题意是有n堆物品每堆ai个,有两种操作:

1.从一堆非空的里面拿走一个

2.将一堆偶数数量分成k堆,每堆的数量是原来的一半.

k有10的9次,显然是有某些规律.首先当k是偶数的时候很容易发现规律,前两个是1,2后面一直是01循环;当k是奇数时发现除掉前四个,后面的奇数位都是0;偶数位没什么规律可以找,但是可以通过lgai的时间求出来,因为是偶数并且k是奇数,如果是拿走一个,这一堆就变成了奇数,sg函数是0,也就是后继状态必然有一个是0,所以我们只需要求出分成k堆的后继状态,k是奇数,k个sg函数的^和相当于施sg(ai/2),规模缩小为一半.这样一来每一种情况的sg函数就都能搞出来了.

复杂度O(n*lg(max (a[i]))).

#include <bits/stdc++.h>
using namespace std;

long long n, k;

int dfs (int num) {
    if (num == 1 || num == 3)
        return 1;
    else if (num == 2)
        return 0;
    else if (num == 4)
        return 2;
    else if (num&1)
        return 0;
    int cur = dfs (num/2);
    if (cur == 0 || cur == 2)
        return 1;
    else if (cur == 1)
        return 2;
}

int sg (long long num) {
    if (k&1) {
        if (num == 1 || num == 3)
            return 1;
        else if (num == 2)
            return 0;
        else if (num == 4)
            return 2;
        else if (num&1)
            return 0;
        else return dfs (num);
    }
    else {
        if (num == 2)
            return 2;
        else if (num == 1)
            return 1;
        else return (num&1) ? 0 : 1;
    }
}

int main () {
    while (cin >> n >> k) {
        long long ans = 0;
        long long num;
        for (int i = 1; i <= n; i++) {
            cin >> num;
            ans ^= sg (num);
        }
        cout << (ans ? "Kevin" : "Nicky") << endl;
    }
    return 0;
}


你可能感兴趣的:(codefoeces 603C (博弈 SG函数找规律))