洛谷1066 2^k进制数
原题链接
大力猜结论竟然猜对了。。
对于一对\(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进制数的更多相关文章
- 洛谷 P1066 2^k进制数
P1066 2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. ( ...
- 洛谷P1066 2^k进制数(题解)(递推版)
https://www.luogu.org/problemnew/show/P1066(题目传送) (题解)https://www.luogu.org/problemnew/solution/P106 ...
- 洛谷P1066 2^k进制数
P1066 2^k进制数 题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. ( ...
- [NOIP2006] 提高组 洛谷P1066 2^k进制数
题目描述 设r是个2^k 进制数,并满足以下条件: (1)r至少是个2位的2^k 进制数. (2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位. (3)将r转换为2进制数q后 ...
- 洛谷P1582——倒水(进制,数学)
https://www.luogu.org/problem/show?pid=1582 题目描述 一天,CC买了N个容量可以认为是无限大的瓶子,开始时每个瓶子里有1升水.接着~~CC发现瓶子实在太多了 ...
- 【洛谷p1066】2^k进制数
(不会敲键盘惹qwq) 2^k进制数[传送门] 算法标签: (又是一个提高+省选-的题) 如果我说我没听懂你信吗 代码qwq: #include<iostream> #include< ...
- [转]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 ...
- 1813. M进制数问题
1813. M进制数问题 Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description 试用 C++的类来表示一般进制数. 给定 2 ...
- 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 ...
随机推荐
- 拓扑排序-有向无环图(DAG, Directed Acyclic Graph)
条件: 1.每个顶点出现且只出现一次. 2.若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面. 有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说. 一 ...
- Excel添加下拉菜单
一.选中需要下拉菜单的单元格 二.数据--数据校验 三 .选择序列,填写来源 四.保存
- 求前n项的斐波那契数列、求两个数的最小公倍数、求两个数的最大公约数
class Fib(object): def __call__(self,n): a=[0,1] for i in range(n-2): an ...
- @Scope 注解
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)这个是说在每次注入的时候回自动创建一个新的bean实例 @Scope(value=Config ...
- Global Illumination
[Global Illumination] Global Illumination (GI) is a system that models how light is bounced off of s ...
- Linux中systemctl命令详细介绍
Linux Systemctl是一个系统管理守护进程.工具和库的集合,用于取代System V.service和chkconfig命令,初始进程主要负责控制systemd系统和服务管理器.通过Syst ...
- JMeter学习(十八)JMeter处理Cookie与Session(转载)
转载自 http://www.cnblogs.com/yangxia-test 有些网站保存信息是使用Cookie,有些则是使用Session.对于这两种方式,JMeter都给予一定的支持. 1.Co ...
- CentOS 系统时间与硬件时间
date 系统时间查看 date -s 'YYYYMMDD HHMMSS' 设置系统时间 hwclock 硬件时间查看 hwclock -w 将系统时间同步到硬件时间 cp /usr/share/zo ...
- 项目的发布(nginx、uwsgi、django、virtualenv、supervisor)
导论 WSGI是Web服务器网关接口.它是一个规范,描述了Web服务器如何与Web应用程序通信,以及Web应用程序如何链接在一起以处理一个请求,(接收请求,处理请求,响应请求) 基于wsgi运行的框架 ...
- POJ-3078.Shuffle'm Up(简单模拟题)
这道题做了有四个小时吧,今天一整天都处于边玩边学的状态,我很是不喜欢...一开始用了20分钟模拟,过了样例后TLE了,就在考虑是不是判断是否重复判定的数组开大了,结果一直蛙,后面想到了map判重,结果 ...