分析

显然可以转化为阶梯nim。

于是问题转化为了对于所有\(i \in [0,n-m]\),求长度为\(\lfloor\frac{m+1}{2}\rfloor\),和为\(i\),异或和非\(0\)的非负整数序列的个数。

直接DP看似不太可行,然而UOJ群的dalao们告诉博主可以按位DP。

令\(f[i][j][0/1]\)表示考虑了后\(i\)位,当前的和为\(j\),后\(i\)位的异或和是否为\(0\)的方案数,转移时枚举当前位有多少个\(1\),类似数位DP那样就好。

最后用隔板法统计答案即可。

记搜的话直接记搜可能过不去,加些剪枝就好了。

代码

#include <bits/stdc++.h>

#define rin(i,a,b) for(int i=(a);i<=(b);++i)
#define irin(i,a,b) for(int i=(a);i>=(b);--i)
#define trav(i,a) for(int i=head[a];i;i=e[i].nxt)
#define Size(a) (int)a.size()
#define pb push_back
#define mkpr std::make_pair
#define fi first
#define se second
#define lowbit(a) ((a)&(-(a)))
typedef long long LL; using std::cerr;
using std::endl; inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int MOD=1e9+9;
const int MAXN=150005; int n,m,cnt;
int fac[MAXN+50],invf[MAXN+50];
int f[20][MAXN][2]; inline int qpow(int x,int y){
int ret=1,tt=x%MOD;
while(y){
if(y&1)ret=1ll*ret*tt%MOD;
tt=1ll*tt*tt%MOD;
y>>=1;
}
return ret;
} inline int binom(int n,int m){
if(n<0||m<0||n<m)return 0;
return 1ll*fac[n]*invf[n-m]%MOD*invf[m]%MOD;
} int dfs(int pos,int sum,int have1){
if(sum&((1<<pos)-1))return 0;
if(pos>17){
if(sum==0&&have1)return 1;
else return 0;
}
if(f[pos][sum][have1]!=-1)return f[pos][sum][have1];
int ret=0;
rin(i,0,cnt){
if((1ll<<pos)*i>sum)break;
ret=(ret+1ll*dfs(pos+1,sum-(1ll<<pos)*i,have1|(i&1))*binom(cnt,i))%MOD;
}
return f[pos][sum][have1]=ret;
} void init(){
fac[0]=1;
rin(i,1,n+m)fac[i]=1ll*fac[i-1]*i%MOD;
invf[n+m]=qpow(fac[n+m],MOD-2);
irin(i,n+m-1,0)invf[i]=1ll*invf[i+1]*(i+1)%MOD;
} int main(){
memset(f,-1,sizeof f);
n=read(),m=read();init();
cnt=(m+1)/2;
int ans=0,box=(m&1)==0?cnt+1:cnt;
rin(i,0,n-m){
int rem=n-m-i;
ans=(ans+1ll*dfs(0,i,0)*binom(rem+box-1,box-1))%MOD;
}
printf("%d\n",ans);
return 0;
}

[VIJOS2055][SDOI2019]移动金币:DP+组合数学的更多相关文章

  1. CF_229E_Gift_概率DP+组合数学

    CF_229E_Gift_概率DP+组合数学 题目描述: 很久很久以前,一位老人和他的妻子住在蔚蓝的海边.有一天,这位老人前去捕鱼,他捉到了一条活着的金鱼.鱼说:“噢,老渔人!我祈求你放我回到海里,这 ...

  2. [多校联考2019(Round 5 T3)]青青草原的表彰大会(dp+组合数学)

    [多校联考2019(Round 5)]青青草原的表彰大会(dp+组合数学) 题面 青青草原上有n 只羊,他们聚集在包包大人的家里,举办一年一度的表彰大会,在这次的表彰大会中,包包大人让羊们按自己的贡献 ...

  3. [Codeforces722E] Research Rover (dp+组合数学)

    [Codeforces722E] Research Rover (dp+组合数学) 题面 给出一个N*M的方格阵,从(1,1)出发,到(N,M)结束,从(x,y)只能走到(x+1,y)或(x,y+1) ...

  4. # [SDOI2019]移动金币 阶梯博弈 dp

    [SDOI移动金币 链接 vijos 思路 阶梯博弈,dp统计. 参见wxyww 代码 #include <bits/stdc++.h> using namespace std; cons ...

  5. [SDOI2019]移动金币(博弈论+阶梯Nim+按位DP)

    首先可以把问题转化一下:m堆石子,一共石子数不超过(n-m)颗,每次可以将一堆中一些石子推向前一堆,无法操作则失败,问有多少种方法使得先手必胜? 然后这个显然是个阶梯Nim,然后有这样的结论:奇数层异 ...

  6. P5363-[SDOI2019]移动金币【阶梯博弈,dp,组合数学】

    正题 题目链接:https://www.luogu.com.cn/problem/P5363 题目大意 \(1\times n\)的网格上有\(m\)个硬币,两个人轮流向前移动一个硬币但是不能超过前一 ...

  7. CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)

    问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高 ...

  8. CF_402F dp+组合数学

    题目链接:http://codeforces.com/problemset/problem/403/D /**算法分析: 这道题综合的考察了dp背包思想和组合数学 */ #include<bit ...

  9. 【BZOJ 3294】 3294: [Cqoi2011]放棋子 (DP+组合数学+容斥原理)

    3294: [Cqoi2011]放棋子 Description Input 输入第一行为两个整数n, m, c,即行数.列数和棋子的颜色数.第二行包含c个正整数,即每个颜色的棋子数.所有颜色的棋子总数 ...

随机推荐

  1. redis在php中实际应用-hash

    Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象. 目录: 1.批量赋值:hmset,hmget,hgetall 可用于存储一条条数据,即一个 ...

  2. WPF使用资源图片

    一.加载本项目的图片 WPF引入了统一资源表示Uri来标识和访问资源.其中较为常见的情况是用Uri加载图像.Uri表达式的一把形式为:协议+授权+路径 协议:pack:// 授权:有两种,一种用于访问 ...

  3. 设置Cookies

    设置Cookies: public ActionResult Index() { // if (Request.Cookies["user"] != null) { //Serve ...

  4. luogu P3826 [NOI2017]蔬菜

    luogu 那个第一次购买有\(s_i\)奖励,可以看成是多一种蔬菜\(i+n\),权值为\(w_i+s_i\),每天减少量\(x\)为0个,保质期\(\lceil\frac{c_i}{x_i}\rc ...

  5. 北上广Java开发月薪20K往上,该如何做,需要会写什么

    这个问题可能很多人会说这只是大企业或者互联网企业工程师才能拿到.也许是的,小公司或者非互联网企业拿两万的不太可能是码农了,应该已经转管理.还有区域问题,这个不在我的考虑范围内,因为这方面除了北上广深杭 ...

  6. Maven中setting.xml 配置详解

    文件存放位置 全局配置: ${M2_HOME}/conf/settings.xml 用户配置: ${user.home}/.m2/settings.xml note:用户配置优先于全局配置.${use ...

  7. 把两个object对象合并成一个对象 属性名称相同的变为后面对象的值

    object.assign(from,obj)------object.assign(目标对象,被合并的对象)

  8. electron localStorage的bug

    在更新 electron 后有可能会读不到 localStorage 里的数据 推测是 localStorage 写在 Chromium 内核里,更新 electron 同时会更新 Chromium, ...

  9. MySQL5.7修改数据库目录!

    MySQL5.7默认安装,修改之前,停止MySQL服务. 数据库目录:C:\ProgramData\MySQL\MySQL Server 5.7\Data 配置文件:C:\ProgramData\My ...

  10. commons Collections4 MultiMap

    MultiMap<String, Integer> multiMap = new MultiValueMap<>(); multiMap.put("A", ...