1 分析胜负

仅当时候,会陷入无限循环,两者会平手。

大于时候,每个数字总是会变成向下取整,然后再以此规则变化。两人每次选择哪个数字其实没有影响,就看一共要消除多少次,才能让这里所有的数字都变成0。

显然,这和数字的大小有关系,当在的范围内,每个数字要消除1次。

当在的范围内,每个数字要消除次,因为消除一次之后会变成k个的范围内的数字。

同理,在当在的范围内,每个数字要消除次。

以此类推。

对系统初始状态的每个数字,计算要消除多少次并加起来,总的如果是奇数就是那个先手的人赢了,否则就是另一个人赢了。

2 前缀和计算

其实不用前缀和也是能算的,只是之间的所有数字要消除多少次不那么好算,可以写一个计算从到数字全部放在一起一共要消除多少次的函数,这样前面一段的分析就很适合来算这个东西了,然后所求就是看看是奇数还是偶数。

3 程序

#include<bits/stdc++.h>
using namespace std;

int l,r,k;
#define ll long long

ll sum(ll n) {
    //k^0 ~ k^1-1 可1次消除
    //k^1 ~ k^2-1 可1+k次消除
    //k^2 ~ k^3-1 可1+k+k^2次消除
    ll kf = 1;//初始,k的0次方为1
    ll ret = 0;//总消除次数
    ll p = 1;//当前这些数字所需消除次数
    while(kf*k-1<n) {
        ret += p*(kf*k-1 - kf + 1)%2;//反正最后是求差的奇偶,这里模2不影响
        p += k;
        kf = kf*k;
    }
    //最后剩下的那些
    ret += p*(n - kf + 1);
    return ret;
}

int main() {
    while(scanf("%d%d%d",&l,&r,&k)!=EOF) {
        //仅当k=1时会无限循环导致平手
        if(k==1)
            puts("Draw");
        else if(((sum(r)-sum(l-1))&1)==1)//奇数
            puts("XHRlyb");
        else
            puts("Cwbc");
    }
    return 0;
}

//GitHub求star啦:https://github.com/LauZyHou/Algorithm-To-Practice