原题链接

大力猜结论竟然猜对了。。

对于一对\(k,w\),我们可以把\(w\)位划分成\(k\)位一段的形式,每一段就是转换成十进制后的一位,这个从题面的解释中应该可以理解。

先不考虑可能多出(即剩余不足以划成\(k\)位)的一段,这样使得每一位的枚举上界都是\(2 ^ k - 1\),然后我们枚举几位数。

  • \(2\)位数

    十位为\(1\),显然个位只能为\(2\sim 2 ^ k - 1\),共\(2 ^ k - 2\)种。

    十位为\(2\),显然个位只能为\(3\sim 2 ^ k - 2\),共\(2 ^ k - 3\)种。

    \(\dots\)

    这么递推下去,在\(2\)位数的情况下,共\(\sum \limits _{i = 1} ^ {2 ^ k - 2}i\)种。
  • \(3\)位数

    百位为\(1\),显然十位只能为\(2\sim 2 ^ k - 2\),这时我们考虑去取之前计算\(2\)位数得到的结果,因为十位从\(2\)开始,所以共\(\sum \limits _{i = 1} ^ {2 ^ k - 3}i\)种。

    百位为\(2\),显然十位只能为\(3\sim 2 ^ k - 2\),共\(\sum \limits _{i = 1} ^ {2 ^ k - 4}i\)种。

    \(\dots\)

    递推下去,在\(3\)位数的情况下,共\(\sum \limits _{i = 1} ^ {2 ^ k - 3} \sum \limits _{j = 1} ^ i j\)种。
  • \(4\)位数

    同样如上考虑,共\(\sum \limits _{i = 1} ^ {2 ^ k - 4} \sum \limits _{j = 1} ^ i \sum \limits _{k = 1} ^ {j} k\)种。

    \(\dots\)

而这个一堆\(\sum\)的式子其实就相当于每次进行前缀和操作,于是我们就可以依照上面的模式递推下去了。

初始化\(i = 1 \to 2 ^ k - 1,S[i] = i\)。

枚举位数,再枚举首位(注意上界,要保证后面每一位都能填数),累计贡献,然后对\(S\)数组进行前缀和操作即可。

然后考虑不能划分成\(k\)位的那一段,其实只需单独拎出来进行单独枚举计算贡献即可(其实只是改个上界而已)。

因为数据较大,所以要用高精。

我的高精是直接\(copy\)我的高精模板(太懒了

部分细节可看代码。

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N = 210;
const int M = 520;
const int base = 1e8;
struct bigint {//高精模板
int s[N], l;
void CL(){ l = 0; memset(s, 0, sizeof(s)); }
void pr()
{
printf("%d", s[l]);
for (int i = l - 1; i; i--)
printf("%08d", s[i]);
}
ll toint()
{
ll x = 0;
for (int i = l; i; i--)
x = x * base + s[i];
return x;
}
bigint operator = (int b)
{
CL();
do
{
s[++l] = b % base;
b /= base;
} while (b > 0);
return *this;
}
bigint operator + (const ll &b)
{
bigint c = *this;
ll x = b;
for (int i = 1; i <= l && x; i++)
{
x = x + c.s[i];
c.s[i] = x % base;
x /= base;
}
if (x)
c.s[++c.l] = x;
return c;
}
bigint operator + (bigint &b)
{
if (b.l < 3)
return *this + b.toint();
bigint c;
ll x = 0;
int k = l < b.l ? b.l : l;
c.CL();
c.l = k;
for (int i = 1; i <= k; i++)
{
x = x + s[i] + b.s[i];
c.s[i] = x % base;
x /= base;
}
if (x)
c.s[++c.l] = x;
return c;
}
};//以上都是高精模板
bigint s, S[M];
inline int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c < '0' || c > '9'; c = getchar())
p |= c == '-';
for (; c >= '0' && c <= '9'; c = getchar())
x = x * 10 + c - '0';
return p ? -x : x;
}
int main()
{
int i, j, k, w, n, o;
k = re();
w = re();
o = 1 << k;
n = w / k + (w % k ? 1 : 0);//划分段数
w = w % k ? (1 << (w % k)) - 1 : o - n;//计算多出一段的上界,如果没有多出,那上界就是2 ^ k - n,因为要保证后面每一位都能填数。
if (n > o - 1)//若划分出来的段数多于2 ^ k - 1段,这多余的就是没有用的
{
n = o - 1;
w = o - n;
}
for (i = 1; i < o; i++)//初始化
S[i] = i;
for (s = 0, i = 2; i <= n; i++)//枚举位数
{
if (i < n)
for (j = 1; j <= o - i; j++)//枚举首位填什么数,上界为2 ^ k - i
s = s + S[o - i - j + 1];//后一位能填j + 1 ~ (2 ^ k - 1) - (i - 1),共2 ^ k - i - j + 1种
else//特判最后一段,改上界
for (j = 1; j <= w; j++)
s = s + S[o - i - j + 1];
for (j = 1; j <= o - i; j++)//计算前缀和
S[j] = S[j] + S[j - 1];
}
s.pr();
return 0;
}

洛谷1066 2^k进制数的更多相关文章

  1. 洛谷 P1066 2^k进制数

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

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

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

  3. 洛谷P1066 2^k进制数

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

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

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

  5. 洛谷P1582——倒水(进制,数学)

    https://www.luogu.org/problem/show?pid=1582 题目描述 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了 ...

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

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

  7. [转]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 ...

  8. 1813. M进制数问题

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

  9. 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 ...

随机推荐

  1. linux系统上项目部署

    步骤:(特别注意:虚拟机安装的一般是32位的操作系统,jdk也必须使用32位的)查看虚拟机版本:sudo uname --m i686 //表示是32位 x86_64 // 表示是64位 查看是否已经 ...

  2. Web App Manifest

    [Web App Manifest] The web app manifest provides information about an application (such as name, aut ...

  3. cdnbest补充api

    1.应用防火墙---防CC 添加|修改 请求地址: {api_dir}/firewall/anticc 请求方式: PUT 请求参数: frcquency string 触发频率 例:low(低) | ...

  4. linux启动jmeter(二十三),执行./jmeter.sh报错解决方法(转载)

    转载自 http://www.cnblogs.com/yangxia-test 1.l-bash: ./jmeter.sh: Permission denied解决办法:jmeter.sh的执行权限改 ...

  5. python学习day5 常量 运算符补充 流程控制基础

    1.常量 值不会改变的量 python中没有特别的语法定义常量,一般约定用全大写字母命名常量,比如圆周率pi 2.预算符补充 2.1算数运算符 print(10/3)除法运算 print(10//3) ...

  6. nutch笔记

    1.Nutch 是一个开源Java实现的搜索引擎.它提供了我们运行自己的搜索引擎所需的全部工具.包括全文搜索和Web爬虫.

  7. 判断python字典中key是否存在

  8. js保留小数点后面几位的方法

    原文地址: http://www.jb51.net/article/45884.htm 四舍五入以下处理结果会四舍五入: ? 1 2 var num =2.446242342; num = num.t ...

  9. 【转】chrome devtools protocol——Web 性能自动化

    前言 在测试Web页面加载时间时,可能会是这样的: 打开chrome浏览器. 按F12打开开发者工具. 在浏览器上打开要测试的页面 查看开发者工具中Network面板的页面性能数据并记录 或者在开发者 ...

  10. Mycat性能调优指南

    本篇内容来自于网络 JVM调优: 内存占用分两部分:java堆内存+直接内存映射(DirectBuffer占用),建议堆内存 适度大小,直接映射内存尽可能大,两种一起占据操作系统的1/2-2/3的内存 ...