[cf] 石江豪pk李震p2002 SG函数
题目
http://codeforces.com/contest/603/problem/C
描述 Description
题目背景
石江豪最近爱上了一款叫《转熊英兽魔:说穿石路》(Tuhaos of China:Cardpackage)的游戏,这周的乱斗模式十分带感,规则是不会限制场上随从的数量。于是,他找到了李震,想和李震进行一次PK,而李震作为一个竞技游戏大神表示很愿意吊打他。不幸的是,他们的对战陷入了僵局。
鏖战了无数分钟之后进入了残局,石江豪和李震都已经获得了10个法力水晶,场上有n个随从,而且他们都是白板,第i个随从的生命值为ai。他们的牌库都打光了,手上只有隐藏职业的两个神秘法术,两个法术的效果分别是这样的:
1.熔岩爆裂,3费,对一个随从造成一点伤害,冻结所有随从,并将该牌洗入你的牌库。过载(7)
2.转生,2费,消灭一个血量为偶数的随从,然后召唤k个血量为被消灭随从一半的随从,然后在下回合将所有随从的攻击力降为0,并将该牌洗入你的牌库。过载(7)
不幸的是,他们两个的血量都被打成1了,而且都没有装备武器,这也就意味着,每个人在每轮都必须而且只能释放一个法术,而且,如果某人击杀了最后一个随从,他的对手会因为疲劳而炸掉,从而获得胜利。
现在轮到石江豪了,由于上回合他所使用的闪电风暴的过载效果,本回合也只剩3点法力水晶了,李震是大神级人物,当然能算出来每一轮该怎么打,而石江豪就不一样了,他想请问学编程的你,在此局面下,他是否有必胜的机会呢?
输入格式 Input Format
第一行两个整数,分别代表n和k。
第二行n个整数,第i个数代表ai。
输出格式 Output Format
如果石江豪有必胜的策略教李震做人,输出“DaDeBuCuo”。
如果石江豪必然败在李震大神手下,输出“WoHenBaoQian”。
样例输入 Sample Input
2 1
3 4
==========
1 2
3
样例输出 Sample Output
DaDeBuCuo
============
WoHenBaoQian
时间限制 Time Limitation
1s
注释 Hint
数据范围:
对于30%的数据,n≤10,k≤5,ai≤20。
对于100%的数据,1≤n≤100000,1≤k≤1000000000,1≤ai≤1000000000。
来源 Source
来源:
Codeforces Round #334 Div.1 Problem C(603C) Lieges of Legendre
数据生成:闵梓轩
真心觉得这个题面比原来的棒
题解
分别讨论k是偶数和奇数的情况。
如果k是偶数
当选择2时,有k个n个石子的小堆,状态的SG函数显然为
。
此时我们可以计算得出
,并且
可证明
,化简得
,或
。
对于
,我们只能移动到
个石子的状态(游戏1),又
,所以
。
对于
,可以移动到
的状态(游戏1),或者游戏2,游戏1和2的sg函数值都为0,所以
。
如果k是奇数
此时对于2n个石子的石堆,状态的SG函数为
。
推导出
。
可证明
。
对于
。
对于
,可以移动到
。
且
递归计算即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
inline int read()
{
int f=1,num=0;
char ch=getchar();
while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
while (isdigit(ch)) num=(num<<1)+(num<<3)+(ch^48), ch=getchar();
return num*f;
}
int f[]={0,1,0,1,2};
inline int odd(int x)
{
if (x<=4) return f[x];
if (x&1) return 0;
return odd(x/2)==1?2:1;
}
inline int even(int x)
{
if (x<=2) return x;
else return x&1^1;
}
int main()
{
int n=read(),k=read(),ans=0;
for (int i=1;i<=n;++i)
{
int a=read();
if (k&1) ans^=odd(a);
else ans^=even(a);
}
puts(ans?"DaDeBuCuo":"WoHenBaoQian");
// puts(ans?"Kevin":"Nicky");
return 0;
}