Luogu P5363 [SDOI2019]移动金币
话说这题放在智推里好久了的说,再不写掉对不起自己233
首先你要知道一个叫做阶梯Nim的东西,具体的可以看这篇博客
那么我们发现这和这道题的关系就很明显了,我们把两个金币之间的距离看作阶梯Nim的每一堆的石子个数
考虑阶梯Nim的结论:奇数编号堆的石子异或和为\(0\),发现我们可以搞一个很暴力的DP出来
\(f_{i,j,k}\)表示当前放了前\(i\)堆石子,总共用了石子个数是\(j\),其中奇数堆石子的异或和为\(k\)的方案数,转移的时候直接枚举当前堆拿了几个即可,复杂度\(O(n^3\times m)\),显然无法通过此题
我们再来冷静一下,发现限制的条件是异或,那么果断想到从二进制的角度出发
先容斥一下,令\(f_{i,j}\)表示做了前\(i\)位的,奇数堆和为\(j\)且异或和为\(0\)的方案数,最后用隔板法综合偶数堆的情况然后用\(C_n^m\)减去即可
然后DP就很好转移了,我们从高到低枚举二进制位,然后枚举奇数堆的和,剩下枚举这一位是\(1\)的奇数堆的个数(显然必须为偶数),然后转移的时候乘上组合数即可
复杂度\(O(nm\times \log n)\),足以通过本题的数据范围。当然提一下这题还有利用进位角度考虑然后再用MTT优化的\(O(m\log m\log n)\)的优秀做法因此是可以出一个加强版的233
#include<cstdio>
#define RI register int
#define CI const int&
using namespace std;
const int N=200005,R=20,mod=1e9+9;
int n,m,f[R][N],odd,even,num,ret,fact[N],inv[N];
inline void inc(int& x,CI y)
{
if ((x+=y)>=mod) x-=mod;
}
inline int sub(CI x,CI y)
{
int t=x-y; return t<0?t+mod:t;
}
inline int quick_pow(int x,int p=mod-2,int mul=1)
{
for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
inline void init(CI n)
{
RI i; for (fact[0]=i=1;i<=n;++i) fact[i]=1LL*fact[i-1]*i%mod;
for (inv[n]=quick_pow(fact[n]),i=n-1;~i;--i) inv[i]=1LL*inv[i+1]*(i+1)%mod;
}
inline int C(CI n,CI m)
{
return 1LL*fact[n]*inv[m]%mod*inv[n-m]%mod;
}
int main()
{
RI i,j,k; scanf("%d%d",&n,&m); init(n+m);
for (odd=m+1>>1,even=m+1-odd,num=n-m,f[R-1][num]=1,i=R-2;~i;--i)
for (j=0;j<=num;++j) for (k=0;j+(1<<i)*k<=num&&k<=odd;k+=2)
inc(f[i][j],1LL*f[i+1][j+(1<<i)*k]*C(odd,k)%mod);
for (i=0;i<=num;++i) inc(ret,1LL*f[0][i]*C(i+even-1,even-1)%mod);
return printf("%d",sub(C(n,m),ret)),0;
}
Luogu P5363 [SDOI2019]移动金币的更多相关文章
- luogu P3878 [TJOI2010]分金币
[返回模拟退火略解] 题目描述 今有 nnn 个数 {ai}\{a_i\}{ai},把它们分成两堆{X},{Y}\{X\},\{Y\}{X},{Y},求一种分配使得∣∑i∈Xai−∑i∈Yai∣|\ ...
- 【洛谷5363】[SDOI2019] 移动金币(动态规划)
点此看题面 大致题意: 有\(n\)个格子,让你摆放\(m\)个金币.二人博弈,每次选择一个金币向左移任意格,无法移动者输.问有多少种方案使先手必胜. 阶梯\(Nim\) 阶梯\(Nim\)的基本模型 ...
- # [SDOI2019]移动金币 阶梯博弈 dp
[SDOI移动金币 链接 vijos 思路 阶梯博弈,dp统计. 参见wxyww 代码 #include <bits/stdc++.h> using namespace std; cons ...
- luogu P5358 [SDOI2019]快速查询【模拟(?)】
把有单点修改和查询的点离散进一个数组,然后单点修改直接改,记录一个修改时间t,维护一个sm表示这些离散的点的和,val表示出了离散点其他点的值,因为都是一样的所以只记录这一个值即可,记录ljlc为加法 ...
- [SDOI2019] 移动金币
分析 阶梯NIM模型:共有m+1堆石子,石子总数不超过n-m,求必胜的,即奇数堆石子数目异或和非零的局面数.补集转化,答案C(n,m)-奇数堆石子数目异或和位0的局面数. 可以想到按位dp,设f[i, ...
- 【题解】Luogu P5358 [SDOI2019]快速查询
原题传送门 神鱼说这道题是强制离线(smog 我们珂以把被单点修改,单点查询的点单独拿出来处理,把每个数表示成\(mul*x+plus\) 初始状态下\(mul=1,plus=0\) 操作1:在总和中 ...
- 【题解】Luogu P5360 [SDOI2019]世界地图
原题传送门 每次查询的实际就是将地图的一个前缀和一个后缀合并后的图的最小生成树边权和 我们要预处理每个前缀和后缀的最小生成树 实际求前缀和(后缀和)的过程珂以理解为上一个前缀和这一列的最小生成树进行合 ...
- 【题解】Luogu P5361 [SDOI2019]热闹又尴尬的聚会
原题传送门 构造题. 明显p,q都越大越好 我们考虑每次取出度最小的点,加到尴尬聚会的集合中(因为把与它相邻的点全删了,不珂能出现认识的情况),把它自己和与自己相连的点从图上删掉(边也删掉),记下这个 ...
- Luogu5363 SDOI2019移动金币(博弈+动态规划)
容易想到可以转化为一个有m堆石子,石子总数不超过n-m的阶梯博弈.阶梯博弈的结论是相当于只考虑奇数层石子的nim游戏. nim和不为0不好算,于是用总方案数减掉nim和为0的方案数.然后考虑dp,按位 ...
随机推荐
- 【2019.10.7 CCF-CSP-2019模拟赛 T2】绝对值(abs)(线段树细节题)
找规律 设\(p_i=a_{i+1}-a_i\),则答案就是\(\sum_{i=1}^{n-1}p_i\). 考虑若将\(a_i\)加上\(x\)(边界情况特殊考虑),就相当于是将\(p_{i-1}\ ...
- Groovy元编程简明教程
同函数式编程类似,元编程,看上去像一门独派武学. 在 <Ruby元编程>一书中,定义:元编程是运行时操作语言构件的编程能力.其中,语言构件指模块.类.方法.变量等.常用的主要是动态创建和访 ...
- IT兄弟连 HTML5教程 HTML语言的语法 1
HTML是文本类型的语言,和其他任何一门语言相比,语法都是最简单的.但在编写HTML文件时,必须遵循HTML的语法规则.一个完整的HTML文件由标题.段落.列表.表格.文本,即嵌入的各种对象所组成,这 ...
- 10、Fiddler中设置断点修改Response
当然Fiddler中也能修改Response 第一种:打开Fiddler 点击Rules-> Automatic Breakpoint ->After Response (这种方法会中 ...
- 框架基础:深入理解Java注解类型(@Annotation)
注解的概念 注解的官方定义 首先看看官方对注解的描述: An annotation is a form of metadata, that can be added to Java source co ...
- Elasticsearch Query DSL 语言介绍
目录 0. 引言 1. 组合查询 2. 全文搜索 2.1 Match 2.2 Match Phase 2.3 Multi Match 2.4 Query String 2.5 Simple Query ...
- java基础(17):包装类、System、Math、Arrays、大数据运算
1. 基本类型包装类 大家回想下,在第三篇文章中我们学习Java中的基本数据类型时,说Java中有8种基本的数据类型,可是这些数据是基本数据,想对其进行复杂操作,变的很难.怎么办呢? 1.1 基本类型 ...
- 用Python复制文件的9个方法
Python 中有许多"开盖即食"的模块(比如 os,subprocess 和 shutil)以支持文件 I/O 操作.在这篇文章中,你将会看到一些用 Python 实现文件复制的 ...
- 完美解决linux下vim在终端不能用鼠标复制的问题
在vim 中输入 :set mouse=r 就行了,还不行的话 :set mouse=v
- CSS元素显示模式
CSS的元素显示模式 什么是元素显示模式 作用:网页的标签非常多,在不同的地方会用到不同类型的标签,了解他们的特点可以更好的布局我们的网页 元素的显示模式就是元素(标签)以什么样的方式进行显示,比如& ...