CF103C Russian Roulette
题目描述
在奥兰多发生的所有事件之后,Sasha 和 Roma 决定找出谁才是队伍中最大的“失败者”。幸运的是,Masha 不知从哪里找来了一把有 $n$ 个弹仓、可以装下恰好 $k$ 发子弹的左轮手枪,现在两人终于有机会一决高下。
Sasha 可以任选 $n$ 个弹仓中的 $k$ 个来装子弹。Roma 会旋转弹仓,使得每一种弹仓的初始位置都是等概率的。然后游戏开始,玩家轮流行动,Sasha 先手:他把枪对准自己的头并扣动扳机。如果扳机前没有子弹,弹仓会向左旋转一格,然后把枪交给 Roma,Roma 也做同样的动作。游戏持续进行,直到有人中弹,幸存者获胜。
Sasha 不想输,所以他必须选择子弹的位置,使得自己输掉的概率最小。在所有能使自己输掉概率最小的方案中,他还要选择字典序最小的那一种,其中空弹仓的字典序小于有子弹的弹仓。
更正式地说,有 $n$ 个弹仓、可以装 $k$ 发子弹的左轮手枪可以表示为一个长度为 $n$ 的字符串。恰好有 $k$ 个字符是 "X"(表示有子弹),其余的是 "."(表示空弹仓)。
我们来描述一下射击的过程。假设扳机正对着字符串的第一个字符(第一个弹仓)。如果这次射击没有击中任何人,弹仓会向左旋转一格,于是字符串也向左循环移动一位。这样,原本的第一个字符变成最后一个,第二个字符变成第一个,依此类推。但扳机的位置始终在字符串的第一个字符前。
在所有能使 Sasha 输掉概率最小的字符串中,他会选择字典序最小的那一个。根据这个字符串,他会装填子弹。你需要帮助 Sasha 装填子弹。对于每个 $x_i$ 查询,回答该位置上是否有子弹。
输入格式
第一行包含三个整数 $n$、$k$ 和 $p$($1 \leq n \leq 10^{18}, 0 \leq k \leq n, 1 \leq p \leq 1000$)——弹仓的数量、子弹的数量和查询的数量。接下来有 $p$ 行,每行一个整数 $x_i$($1 \leq x_i \leq n$),表示要查询的弹仓编号。
请不要在 C++ 中使用 %lld 读取或输出 64 位整数。建议使用 cin、cout 流或 %I64d 格式。
输出格式
对于每个查询,如果该弹仓应为空,输出 ".",如果应有子弹,输出 "X"。
说明/提示
字符串的字典序比较在现代编程语言中通过 < 运算符实现。字符串 $a$ 的字典序小于字符串 $b$,当且仅当存在某个 $i$($1 \leq i \leq n$),使得 $a_i < b_i$,且对于所有 $j$($1 \leq j < i$)都有 $a_j = b_j$。
由 ChatGPT 4.1 翻译