牛客小白月赛2 E 是是非非 【尼姆博弈】

链接:https://www.nowcoder.com/acm/contest/86/E
来源:牛客网

题目描述

坎为水,险阳失道,渊深不测;离为火,依附团结,光明绚丽。
坎卦:水洊至,习坎;君子以常德行,习教事。一轮明月照水中,只见影儿不见踪,愚夫当财下去取,摸来摸去一场空。
离卦:明两作,离,大人以继明照四方。官人来占主高升,庄农人家产业增,生意买卖利息厚,匠艺占之大亨通。 
有一些石子堆,第 堆有 个石子。你和算卦先生轮流从任一堆中任取若干颗石子(每次只能取自一堆,并且不能不取),取到最后一颗石子的人获胜。 
算卦先生来问你,如果你先手,你是否有必胜策略?若是改动其中几个石子堆中石子的数量呢?

输入描述:

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

输出描述:

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

输入

复制
5 4
6 7 3 4 5
1 6
2 1
2 4
5 5

输出

复制
Kan
Kan
Li
Li

备注:




 
思路:
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 }

 

posted @ 2018-07-31 21:49  佰大于  阅读(197)  评论(0编辑  收藏  举报