001 题目描述:

坎为水,险阳失道,渊深不测;离为火,依附团结,光明绚丽。
坎卦:水洊至,习坎;君子以常德行,习教事。一轮明月照水中,只见影儿不见踪,愚夫当财下去取,摸来摸去一场空。
离卦:明两作,离,大人以继明照四方。官人来占主高升,庄农人家产业增,生意买卖利息厚,匠艺占之大亨通。

有一些石子堆,第 堆有个石子。你和算卦先生轮流从任一堆中任取若干颗石子(每次只能取自一堆,并且不能不取),取到最后一颗石子的人获胜。
算卦先生来问你,如果你先手,你是否有必胜策略?若是改动其中几个石子堆中石子的数量呢?

010 输入描述:

第一行两个正整数 表示有 个石堆,次操作。
第二行 个整数,第 个数 表示第 个石堆初始有石子。
接下去 行,每行两个正整数,表示把第 堆石子的个数修改成 。操作是累计的,也就是说,每次操作是在上一次操作结束后的状态上操作的。

011 输出描述:

行,输出每次操作之后先手是否有必胜策略。
如果有,输出 ,否则输出

100 样例:

输入:

5 4
6 7 3 4 5
1 6
2 1
2 4
5 5

输出:

Kan
Kan
Li
Li

101备注:


110思路:

Nim博弈问题,当且仅当每一堆的石子数的异或和为0时,先手没有必胜策略,因此需要维持一个异或和,每次修改的时候将其和旧数异或,然后再次后修改后的新数异或,因为abb = a。
类似的题目:
P1247 取火柴游戏
AC代码

#include<cstdio>
#include<iostream>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
const int N = 1e5 + 5;
int num[N];
int main(){
    int n,q;
    cin >> n >> q;
    int check = 0;
    for(int i = 0;i < n;i++){
        cin >> num[i];
        check ^= num[i];
    }
    while(q--){
        int x,y;
        cin >> x >> y;
        check ^= num[x - 1];
        check ^= y;
        num[x - 1] = y;
        if(check)
            cout << "Kan" << endl;
        else
            cout << "Li" << endl;
    }
    return 0;
}