题面

传送门:https://www.luogu.org/problemnew/show/P1066


Solution

这是一道神奇的题目,我们有两种方法来处理这个问题,一种是DP,一种是组合数。

这题需要高精度,以下省略此声明

.

如果你对数学不感兴趣/喜欢写DP/(不想虐待自己),这里是DP做法。

首先,我们可以发现,这个数最多有w/k位(向上取整),如下图所示:

那么,我们就可以以这个特性做DP啦。

设f[i][j]表示枚举到第i位(指2^k进制下的),最后一位数为j。

f[i][j] = ∑ f[i-1][k] ((j==0 and k==0) or k<j) 

这里的k显然是可以用前缀和优化的

初始化 f[1][i]=1 (i=0~2^(w%k)-1)

当然,还有一些小细节:f[倒数第2/第1个][0]=0

答案为∑f[w/k][i] 

(因为我没写过DP做法,这个做法纯口胡,如有错误请通知蒟蒻博主)


那....组合数呢?

事实上,这题的组合数做法的确很妙,(当然也有不少细节)

假设我们枚举了第一位数,那么后面位数的方案数是可以通过组合数来计算出来的。

因为后面的数要比第一位大,那么后面的数相当于从 [第一位数+1,2^k-1] 这个数的区间中选出x个数(x为后面的位数数量)来 (因为每一种方案都可以通过摆成升序满足题目要求)。

但是考虑到有可能有若干个前导零,我们还要枚举第一个位数从哪开始。

因为枚举了前导零,我们枚举第一位数时应该从1开始(从0开始会有重复)

这样子,答案为:

(事实上口胡起来简单,写起来还有很多细节,这得亲自体会然后就会感到这题的毒瘤)

就酱,我们就可以切掉嘴巴AC出这道题啦(~ ̄▽ ̄)~


Code

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct Int128
{
static const int N=500;
int a[N],len;
Int128()
{
memset(a,0,sizeof a);
len=0;
}
void Print()
{
for(int i=len;i>=1;i--)
printf("%d",a[i]);
}
friend Int128 operator * (Int128 A,int B)
{
for(int i=1;i<=A.len;i++)
A.a[i]*=B;
bool IsFullZero=true;
for(int i=1;i<=A.len;i++)
{
if(A.a[i]>=10)
{
A.a[i+1]+=A.a[i]/10,A.a[i]%=10;
if(i==A.len and A.a[i+1]!=0)
A.len++;
}
if(A.a[i]!=0) IsFullZero=false;
}
if(IsFullZero==true) A.len=1;
return A;
}
friend Int128 operator / (Int128 A,int B)
{
Int128 ans;
int temp=0;
for(int i=A.len;i>=1;i--)
{
temp=temp*10+A.a[i];
if(temp>=B)
{
ans.a[i]=temp/B,temp=temp%B;
ans.len=max(ans.len,i);
}
}
return ans;
}
friend Int128 operator + (Int128 A,Int128 B)
{
if(A.len<B.len) swap(A,B);
for(int i=1;i<=A.len;i++)
{
A.a[i]=A.a[i]+B.a[i];
if(A.a[i]>9)
{
A.a[i+1]++;A.a[i]-=10;
if(i==A.len)
A.len++;
}
}
return A;
}
};
const int N=1<<(9+1);
Int128 C[N];
int n,x,K,w,first,m;
int main()
{
scanf("%d%d",&K,&w); first=1<<(w%K),x=w/K;
if(w%K==0)
first=1<<K,x--;
m=1<<K; Int128 ans;
for(int j=0;j<=x-1;j++)
{
int tx=x-j;
memset(C[tx].a,0,sizeof C[tx].a);
C[tx].a[1]=1,C[tx].len=1;
for(int i=tx+1;i<=m;i++)
{
memset(C[i].a,0,sizeof C[i].a);
C[i]=(C[i-1]*i)/(i-tx);
}
if(j!=0) first=m;
for(int i=1;i<m and i<first;i++)
{
if(m-1-i<tx) break;
ans=ans+C[m-1-i];
}
//ans.Print();
//cerr<<endl;
} ans.Print();
return 0;
}

[Luogu P1066] 2^k进制数 (组合数或DP)的更多相关文章

  1. [luogu]P1066 2^k进制数[数学][递推][高精度]

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

  2. Luogu P1066 2^k进制数 组合数学

    分两种情况:$k|n$和$k$不整除$n$ 如果$k|n$,那么长度为$n$的二进制数就能被恰好分成$n/k$个块:所以若某个数长度是$x$个块,由于每个块内能填不同的$2^k-1$个数,那么就有$C ...

  3. 洛谷P1066 2^k进制数

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

  4. 洛谷 P1066 2^k进制数

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

  5. 洛谷P1066 2^k进制数(题解)(递推版)

    https://www.luogu.org/problemnew/show/P1066(题目传送) (题解)https://www.luogu.org/problemnew/solution/P106 ...

  6. [NOIP2006] 提高组 洛谷P1066 2^k进制数

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

  7. P1066 2^k进制数

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

  8. 【洛谷p1066】2^k进制数

    (不会敲键盘惹qwq) 2^k进制数[传送门] 算法标签: (又是一个提高+省选-的题) 如果我说我没听懂你信吗 代码qwq: #include<iostream> #include< ...

  9. 一本通1649【例 2】2^k 进制数

    1649:[例 2]2^k 进制数 时间限制: 1000 ms         内存限制: 524288 KB [题目描述] 原题来自:NOIP 2006 提高组 设 r 是个 2k 进制数,并满足以 ...

随机推荐

  1. Go-archive/tar: write after close gopher.txt

    where? 在使用Go中tar包循环写入内容的时候 why? 因为已经关闭了tar.writer对象,所以无法写入,但是程序还是有写入操作,所以报错 way? 通过 defer关键字来管理资源的释放 ...

  2. Leetcode PHP题解--D125 107. Binary Tree Level Order Traversal II

    val = $value; } * } */ class Solution { private $vals = []; /** * @param TreeNode $root * @return In ...

  3. 【题解】hdu4757 【TJOI2018】异或

    题目链接 题目大意:有一颗树,有点权,每次询问:一条路径\(x->y\)中与\(z\)异或的最大值,或是以\(x\)为根的子树中与\(y\)异或的最大值. 树剖--还是算了. 观察到,子树的\( ...

  4. vscode设置snippets

    自动添加文件描述信息 "File Comments": { "prefix": "filecomments", "body&quo ...

  5. pytest文档50-命令行参数--durations统计用例运行时间

    前言 写完一个项目的自动化用例之后,发现有些用例运行较慢,影响整体的用例运行速度,于是领导说找出运行慢的那几个用例优化下. --durations 参数可以统计出每个用例运行的时间,对用例的时间做个排 ...

  6. pytest文档49-命令行参数--tb的使用

    前言 pytest 使用命令行执行用例的时候,有些用例执行失败的时候,屏幕上会出现一大堆的报错内容,不方便快速查看是哪些用例失败. --tb=style 参数可以设置报错的时候回溯打印内容,可以设置参 ...

  7. web自动化测试总结

    web自动化: 1.测试用例(操作步骤,熟读需求文档,web项目先用手工研究,前置条件,预期结果) 接口自动化测试中数据功能最适合作为数据驱动,数据放在excel中需要操作excel 为什么web自动 ...

  8. centos8平台nginx服务配置打开文件限制max open files limits

    一,nginx启动时提示打开文件数,ulimit的配置不起作用: 1, 2020/04/26 14:27:46 [notice] 1553#1553: getrlimit(RLIMIT_NOFILE) ...

  9. selenium基础--登录简单的网站

    import time from selenium import webdriver from lxml import etree from selenium.webdriver import Act ...

  10. dom4j api 详解【转】

    1.DOM4J简介 DOM4J是 dom4j.org 出品的一个开源 XML 解析包.DOM4J应用于 Java 平台,采用了 Java 集合框架并完全支持 DOM,SAX 和 JAXP. DOM4J ...