链接:https://www.nowcoder.com/acm/contest/86/E
来源:牛客网
题目描述
坎为水,险阳失道,渊深不测;离为火,依附团结,光明绚丽。
坎卦:水洊至,习坎;君子以常德行,习教事。一轮明月照水中,只见影儿不见踪,愚夫当财下去取,摸来摸去一场空。
离卦:明两作,离,大人以继明照四方。官人来占主高升,庄农人家产业增,生意买卖利息厚,匠艺占之大亨通。
有一些石子堆,第 堆有 个石子。你和算卦先生轮流从任一堆中任取若干颗石子(每次只能取自一堆,并且不能不取),取到最后一颗石子的人获胜。
算卦先生来问你,如果你先手,你是否有必胜策略?若是改动其中几个石子堆中石子的数量呢?
输入描述:
第一行两个正整数 ,表示有 个石堆, 次操作。
第二行 个整数,第 个数 表示第 个石堆初始有 个石子。
接下去 行,每行两个正整数 ,表示把第 堆石子的个数修改成 。操作是累计的,也就是说,每次操作是在上一次操作结束后的状态上操作的。
输出描述:
共 行,输出每次操作之后先手是否有必胜策略。
如果有,输出 ,否则输出 。
备注:
思路:
1. 使用 尼姆博弈的结论,所有石子 异或 不为零 先手有必胜策略。
2. 由于进行 q 次询问,不停改变石子数量,我们不可每次遍历一遍进行异或操作,利用异或的定义(x^x=0 0^x=x),只需要在旧数据上异或要改变石子数量的旧值,就相当于从原来的石子堆去掉了那个,然后于新的石子数量进行异或即可。
AC码:
1 #include <iostream> 2 using namespace std; 3 int mapp[100000+5]; 4 int main(){ 5 int n,q; 6 int ans=0; 7 cin>>n>>q; 8 for(int i=0;i<n;i++){ 9 cin>>mapp[i]; 10 ans^=mapp[i]; 11 } 12 int x,y; 13 for(int i=0;i<q;i++){ 14 cin>>x>>y; 15 ans^=mapp[x-1]^y; 16 mapp[x-1]=y; 17 if(ans) 18 cout<<"Kan"<<endl; 19 else 20 cout<<"Li"<<endl; 21 } 22 return 0; 23 }