发现自己推得组合数好像不太一样

先把这个复杂的柿子写一遍

\[\sum_{i=2}^{\left \lfloor\frac{n}{k}\right \rfloor}C_{2^k-1}^{i}+\sum_{i=1}^{2^{n\text{ } \text{mod} \text{ }k}-1}C_{2^k-1-i}^{\left \lfloor\frac{n}{k}\right \rfloor}
\]

感觉这个柿子非常蛇皮

但是非常好求啊

由于\(2^k-1\)非常小,最大仅仅是\(511\),所以我们没有什么必要预处理阶乘,我们可以直接用组合数递推的方式来做

于是不需要打高精除或者高精乘了,一个高精加就够了

于是做法就非常无脑了,重要的是这个柿子是怎么推出来的

首先我们先考虑一个非常弱化的版本,就是\(k|n\)

如果\(k|n\)的话,**那么这个长度为\(n\)的二进制数就能被恰好分成\(n/k\)个块,而且每一个块能选择的数都是\(0\)到\(2^k-1\)这\(2^k\)个数

**

我们发现\(0\)这个非常不好考虑,于是我们可以先忽略掉\(0\)

所以现在有\(n/k\)个块,每个块内能填\(2^k-1\)种数

那么就有\(C_{2^k-1}^{n/k}\)种可能

之后我们再来考虑\(0\)的情况,首先最高位(如果不是第二位的话)是可以填\(0\)的,而剩下的\(n/k-1\)个块我们仍旧按照之前的方式来填,于是就有\(C_{2^k-1}^{n/k-1}\),之后对于次高位还是可以填\(0\)(同时最高位也填\(0\)),那么还有\(n/k-2\)个块,于是就是\(C_{2^k-1}^{n/k-2}\)

以此类推,直到对于第三个的块,我们还是可以填将这个块以及之前所有的块都填\(0\),那么就还有\(2\)个块,于是就是\(C_{2^k-1}^{2}\)

而第二个块可是不能填\(0\)了,于是就没了

所以对于\(k|n\)的时候,答案就是

\[\sum_{i=2}^{n/k}C_{2^k-1}^{i}
\]

之后我们再来考虑一下\(k\)不整除\(n\)的情况

这个样子的话一共会分成\(\left \lfloor\frac{n}{k}\right \rfloor+1\)个块,\(\left \lfloor\frac{n}{k}\right \rfloor\)个块内可以选择的数都是\(0\)到\(2^k-1\)这\(2^k\)个数,而最后一个不完整的块只有\(n\text{ } \text{mod} \text{ }k\)位,所以能选择的数只有\(0\)到\(2^{n\text{ } \text{mod} \text{ }k}-1\)

如果这个最高位选择填\(0\)那么退化成了\(k|n\)的情况,所以最高位填0的方案数为

\[\sum_{i=2}^{\left \lfloor\frac{n}{k}\right \rfloor}C_{2^k-1}^{i}
\]

之后最高位还有\(1\)到\(2^{n\text{ } \text{mod} \text{ }k}-1\)这些数可以填,如果我们选择填\(i\)的话,那么剩下的块内就不能填比\(i\)小的数,于是剩下的每个块内能选择的就有\(2^k-1-i\)个数,所以方案数就是\(C_{2^k-1-i}^{\left \lfloor\frac{n}{k}\right \rfloor}\)

所以最后的答案还应该加上

\[\sum_{i=1}^{2^{n\text{ } \text{mod} \text{ }k}-1}C_{2^k-1-i}^{\left \lfloor\frac{n}{k}\right \rfloor}
\]

代码

#include<cstring>
#include<string>
#include<cstdio>
#include<iostream>
#define re register
#define maxn 512
using namespace std;
string c[maxn][maxn];
int n,k;
int p,t;
int res;
int aa[201],bb[201],cc[201];
inline string sum(string a,string b)
{
memset(aa,0,sizeof(aa));
memset(bb,0,sizeof(bb));
memset(cc,0,sizeof(cc));
int lena=a.size();
int lenb=b.size();
for(re int i=0;i<lena;i++)
aa[i+1]=a[lena-i-1]-48;
for(re int i=0;i<lenb;i++)
bb[i+1]=b[lenb-i-1]-48;
int p=1;
for(p=1;p<=max(lena,lenb)||cc[p];p++)
{
cc[p]+=aa[p]+bb[p];
cc[p+1]+=cc[p]/10;
cc[p]%=10;
}
string C="\0";
for(re int i=p-1;i;i--)
C+=char(cc[i]+48);
return C;
}
int main()
{
scanf("%d%d",&k,&n);
p=n/k;
res=n%k;
t=(1<<k);
c[0][0]="1";
for(re int i=1;i<=t-1;i++)
c[i][0]=c[i][i]="1";
for(re int i=1;i<t;i++)
for(re int j=1;j<i;j++)
c[i][j]=sum(c[i-1][j-1],c[i-1][j]);
string ans="0";
for(re int i=2;i<=p;i++)
{
if(i>t-1) break;
ans=sum(ans,c[t-1][i]);
}
int pp=(1<<res)-1;
for(re int i=1;i<=pp;i++)
{
if(p>t-1-i) break;
ans=sum(ans,c[t-1-i][p]);
}
cout<<ans<<endl;
return 0;
}

【2^k进制数】的更多相关文章

  1. [转]as3 算法实例【输出1 到最大的N 位数 题目:输入数字n,按顺序输出从1 最大的n 位10 进制数。比如输入3,则输出1、2、3 一直到最大的3 位数即999。】

    思路:如果我们在数字前面补0的话,就会发现n位所有10进制数其实就是n个从0到9的全排列.也就是说,我们把数字的每一位都从0到9排列一遍,就得到了所有的10进制数. /** *ch 存放数字 *n n ...

  2. 1813. M进制数问题

    1813. M进制数问题 Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description 试用 C++的类来表示一般进制数. 给定 2 ...

  3. CF459C Pashmak and Buses (构造d位k进制数

    C - Pashmak and Buses Codeforces Round #261 (Div. 2) C. Pashmak and Buses time limit per test 1 seco ...

  4. [codevs1157]2^k进制数

    [codevs1157]2k进制数 试题描述 设r是个2k 进制数,并满足以下条件: (1)r至少是个2位的2k 进制数. (2)作为2k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. ...

  5. noip2006 2^k进制数

    设r是个2k进制数,并满足以下条件: (1)r至少是个2位的2k进制数. (2)作为2k进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. (3)将r转换为2进制数q后,则q的总位数不超过w ...

  6. c++描述将一个2进制数转化成10进制数(用到初始化栈,进栈,入栈)

    /* c++描述将2进制数转化成10进制数 问题,1.初始化栈后,用new,不知道delete是否要再写一个函数释放内存, 还是在哪里可以加上delete 2.如果栈满了,我要分配多点空间,我想的办法 ...

  7. 关于不同进制数之间转换的数学推导【Written By KillerLegend】

    关于不同进制数之间转换的数学推导 涉及范围:正整数范围内二进制(Binary),八进制(Octonary),十进制(Decimal),十六进制(hexadecimal)之间的转换 数的进制有多种,比如 ...

  8. NOIP2006 2k进制数

    2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. (3)将r转换 ...

  9. 4位bcd数转换为2进制数

    DATA   SEGMENTBUF    DW  1234HBUF1   DW  ?    ;2进制数放到buf1内存单元DATA   ENDSCODE   SEGMENTASSUME CS:CODE ...

  10. P1066 2^k进制数

    传送门 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. (3)将r转换为2进 ...

随机推荐

  1. 行内元素的margin只能左右有效。上下无效。

    行内元素的margin只能左右有效.上下无效.

  2. Lucence学习之一:全文检索的基本原理

    本文转载自:  http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623594.html 一.总论 根据http://lucene.ap ...

  3. php多进程实现 亲测

    php多进程实现 PHP有一组进程控制函数(编译时需要–enable-pcntl与posix扩展),使得php能在nginx系统中实现跟c一样的创建子进程.使用exec函数执行程序.处理信号等功能. ...

  4. Python下ImportError: DLL load failed: 找不到指定的模块

    环境:Anaconda3 Python3.7 scarpy1.5 版本似乎都能对的上.但是在cmd下报错 如下截图. 从以上错误来看,应该是lxml包有异常. pip uninstall lxml包. ...

  5. JAVA线程池的原理分析

    线程池的作用 1.降低资源的消耗 2.提高效率 3.方便管理 相关概念 corePoolSize核心线程数:核心池的大小,当有任务到达之后,就会创建一个线程去执行任务,当任务数量到达核心线程数后,就会 ...

  6. 百度富文本Ueditor将图片存在项目外路径并回显

    我的毕设中需要一个类似新闻发布的功能,使用到百度富文本编辑器,不过百度富文本编辑器有点坑(只是我太菜了),粘贴图片和回显这个坑坑了我两天时间.效果是这样的: 就是可以在文本中粘贴图片并显示出来,直接说 ...

  7. 一、python简单爬取静态网页

    一.简单爬虫框架 简单爬虫框架由四个部分组成:URL管理器.网页下载器.网页解析器.调度器,还有应用这一部分,应用主要是NLP配合相关业务. 它的基本逻辑是这样的:给定一个要访问的URL,获取这个ht ...

  8. IOC和DI到底是什么?

     在学习Spring框架的时候,我们总是能见到IOC这个单词,也时常听到DI这个词,那么他们分别是什么意思呢?接下来就讲讲个人对于这两个概念的理解  一.IOC和DI概念 IOC(控制反转):全称为: ...

  9. 介绍一款小众的IDE

    作为前端工程师的你们平时主要使用什么IDE,atom.webstorm.sublime还是vscode? 今天介绍一款比较小众的IDE,Adobe的开源项目Brackets,提供Windows和OS ...

  10. Hibernate 性能优化一对一关联映射

    概述: hibernate提供了两种映射一对一关联的方式:按照外键映射和按照主键映射. 下面以员工账号和员工档案为例 ,介绍两种映射方式,并使用这两种映射方式分别完成以下持久化操作: (1)保存员工档 ...