「HNOI 2014」 江南乐

\(Description\)

\(n\)堆石子,每堆石子有\(s_i\)个,两个人轮流操作,每次可以将一对不少于\(F\)的石子尽量平均分成\(m\)堆,\(m\)每次自选,不能操作者输.共有\(T\)组数据

\(Solution\)

\(70\ pts\)

直接\(SG\)搞一搞就好了,枚举堆的个数,异或一下就没了

\(Code\)

#include
#define int long long
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
int sg[100010],mex[100010],f,T;
int SG(int x){
    if(sg[x]!=-1) return sg[x];
    if(x

\(100\ pts\)

假设现在求的是\(x\)\(sg\)值,我们动笔算一算,发现他每次求的都是:

\[\lfloor \frac{x}{i} \rfloor,\lfloor \frac{x}{i+1} \rfloor,\lfloor \frac{x}{i+2} \rfloor,\lfloor \frac{x}{i+3} \rfloor...\]

但是这里面会有很多相等的答案,这个学过整除分块的应该都知道吧.

如果没学过就去看一看,很好理解.

所以对于每一个相同的答案只要计算\(i\)\(i+1\)就好了

\(Code\)

#include
#define int long long
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
    while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*f;
}
int sg[100010],mex[100010],f,T;
int SG(int x){
    if(sg[x]!=-1) return sg[x];
    if(x

转载于:https://www.cnblogs.com/hbxblog/p/10422829.html

你可能感兴趣的:(「HNOI 2014」 江南乐)