ARC091D Strange Nim

Posted asuldb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ARC091D Strange Nim相关的知识,希望对你有一定的参考价值。

题目

显然对每一堆石子求一个SG之后异或起来就好了。

这个SG看起来只能(O(n^2))的样子啊,考虑找规律;

一下是(k=3)时的一些SG函数的值

SG(1): 0 SG(2): 0 SG(3): 1
SG(4): 0 SG(5): 1 SG(6): 2
SG(7): 0 SG(8): 1 SG(9): 3
SG(10): 2 SG(11): 0 SG(12): 4
SG(13): 1 SG(14): 3 SG(15): 5
SG(16): 2 SG(17): 0 SG(18): 6
SG(19): 4 SG(20): 1 SG(21): 7
SG(22): 3 SG(23): 5 SG(24): 8
SG(25): 2 SG(26): 0 SG(27): 9
SG(28): 6 SG(29): 4 SG(30): 10
SG(31): 1 SG(32): 7 SG(33): 11
SG(34): 3 SG(35): 5 SG(36): 12
SG(37): 8 SG(38): 2 SG(39): 13
SG(40): 0 SG(41): 9 SG(42): 14
SG(43): 6 SG(44): 4 SG(45): 15
SG(46): 10 SG(47): 1 SG(48): 16
SG(49): 7 SG(50): 11 SG(51): 17

不难发现一些规律

[ operatorname{SG}(n) = egin{cases} 0 & 0 le n < k \ frac{n}{k} & n mod k = 0 \ displaystyle operatorname{SG} !left(n - !leftlfloor frac{n}{k} ight floor! - 1 ight) & n mod k ! eq 0 end{cases} ]

我们发现直接那这个式子来暴力算复杂度还是(O(n))的,考虑在转移的过程中把(leftlfloor frac{n}{k} ight floor)相等的转移一起做;

(x=lfloor frac{n}{k} floor),则我们需要找到一个最大的(y)满足(n-y(x+1)geq x imes k),即(y=lfloor frac{n-x imes k}{x+1} floor),这中间的转移(lfloor frac{n}{k} floor)是不变的,于是我们可以直接令({ m SG}(n)={ m SG}(n-(x+1)y))

考虑复杂度,当(kleq sqrt{n})时,(leftlfloor frac{n}{k} ight floor>sqrt{n}),于是每次(n)都会至少减去(sqrt{n}),于是这边复杂度是(O(sqrt{n}))的;当(k>sqrt{n})时,(leftlfloor frac{n}{k} ight floorleq sqrt{n}),按照上面的转移方式每进行一次转移(leftlfloor frac{n}{k} ight floor)的值至少会减少(1),于是复杂度也是(O(sqrt{n}))的。

代码

#include<bits/stdc++.h>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
    char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
int T,n,m;
int bf(int n) {
    if(n<m) return 0;if(n%m==0) return n/m;
    return bf(n-n/m-1);
}
int sg(int n) {
    if(n<m) return 0;if(n%m==0) return n/m;
    int x=n/m;int u=x*m;
    int h=(n-u)/(x+1);
    if(n-h*(x+1)==u) return x;
    return sg(n-(h+1)*(x+1));
}
int main() {
    int ans=0;
    for(re int T=read();T;--T) {
        n=read(),m=read();
        if(m<=n/m) ans^=bf(n);
        else ans^=sg(n);
    }
    if(ans) puts("Takahashi");
    else puts("Aoki");
    return 0;
}

以上是关于ARC091D Strange Nim的主要内容,如果未能解决你的问题,请参考以下文章

js 常用代码片段

如何从 Nim 的主块返回退出代码?

Codeforces 832C - Strange Radiation

HDU 2899 Strange fuction 二分

text 如何使用`.C`接口从R调用Nim代码

如何从 Nim 的导入失败中恢复?