原题链接

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

对于一对\(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. yii2.0 手动配置redis

    手动安装yii2.0-redis扩展 1.点击下载:yii2.0-redis扩展 2.把下载的扩展文件放到vendor/yiisoft/下,命名为yii2-redis 3.修改vender/yiiso ...

  2. jquery 获取子元素的限制jquery

    今天练习jqueryAPI发现一个问题就是子元素如果采用nth-child,元素不同就获取不到,因此一个父元素下的子元素标签必须相同,如果不同第一个元素可以用这个方法实现,但是如果第二元素及以后如果出 ...

  3. 04_web基础(四)之servlet详解

    16.17.18.servlet生命周期 javax.servlet.Servlet接口方法:public String getServletInfo():获取Servlet相关信息(作者,版权,版本 ...

  4. win10 壁纸路径

    C:\用户\用户名\AppData\Roaming\Microsoft\Windows\Themes\CachedFiles 原文: https://blog.csdn.net/qq_35040828 ...

  5. JMeter学习(二十四)HTTP属性管理器HTTP Cookie Manager、HTTP Request Defaults(转载)

    转载自 http://www.cnblogs.com/yangxia-test Test Plan的配置元件中有一些和HTTP属性相关的元件:HTTP Cache Manager.HTTP Autho ...

  6. zabbix监控指定端口

    生产上经常会监控某些具体端口状态,下面介绍具体步骤: 主机名 ip 操作系统 zabbix版本 zabbix-server 172.27.9.63 Centos7.3.1611 zabbix_serv ...

  7. Cron 表达式

    Cron表达式是一个字符串,字符串以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式: (1) Seconds Minutes Hours DayofMonth Mo ...

  8. NumPy 统计函数

    NumPy 统计函数 NumPy 提供了很多统计函数,用于从数组中查找最小元素,最大元素,百分位标准差和方差等. 函数说明如下: numpy.amin() 和 numpy.amax() numpy.a ...

  9. 这篇说的是Unity Input 输入控制器

    关于Unity3D是什么.我就不多做解释了.由于工作原因,该系列原创教程不定期更新.每月必然有更新.谢谢各位 Unity Input---输入控制管理器: Edit->Project Setti ...

  10. 微信小程序开发——连续快速点击按钮调用小程序api返回后仍然自动重新调用的异常处理

    前言: 小程序开发中诸如获取用户手机号码.调起微信支付.领取卡券等api都是会有一定的延迟的.也就是说通过点击按钮调用这些api的时候,从点击按钮调用api,到支付页面或者领取卡券界面展示出来是需要一 ...