题目

描述

题目大意

有从111到nnn的数字,每个数字都可以放在一个盒子里(可以不放)。一旦放,满足:

如果它不在第mmm个盒子,那么它的两倍一定在后面一个盒子里。

如果它不在第111个盒子,那么它的一半(整除,如果不能整除即为不合法)一定在前面的一个盒子里。

询问第一个盒子放的最多的数字个数。


思考历程

其实我当时思考的应该是正解,不过有点麻烦。

题目的重点自然在哪两个限制的条件上。首先,显然奇数必须放在第111个盒子里

可以互相影响到的其实是2kx2^kx2kx的形式,其中xxx为奇数。

不妨将每个xxx的这个东西想象成一条链。

如果这条链被放入盒子中,第一项必定在第一个盒子里,然后第二项放第二个盒子里……第mmm项放在第三个盒子里。

当它的项数达不到mmm的时候,意味着这条链连不到最后一个盒子,由第一条限制得这样子不合法。

因此,必须要从头连到尾

对于一个以xxx开头的链,设它的长度为lll,它可以先从头到尾连一遍,然后重新来再连一遍……所以说,它最多可以连⌊lm⌋\lfloor \frac{l}{m} \rfloor⌊ml​⌋层。显然l=⌊log⁡2nx⌋+1l=\lfloor\log_2\frac{n}{x}\rfloor+1l=⌊log2​xn​⌋+1

所以暴力的思路就出来了,枚举奇数xxx,然后计算它对答案的贡献。

显然这样是很慢的,因为xxx的取值有很多。

可是log⁡2x\log_2xlog2​x的取值并不是很多啊!

然后就是第二个思路,枚举yyy(也就是log⁡2x\log_2xlog2​x),这里xxx的取值范围是⌊n2y+1⌋&lt;x≤⌊n2y⌋\lfloor\frac{n}{2^{y+1}}\rfloor&lt;x \leq \lfloor \frac{n}{2^y} \rfloor⌊2y+1n​⌋<x≤⌊2yn​⌋。

我们可以将这段区间内的奇数个数计算出来,计入贡献。

这样子显然要快多了。

再看看高精度的做法,如果是用以前的那种求出111分别到左右边界的奇数个数,然后相减的方法,那么花费的时间一定很多。

所以呢?我就开始分类讨论,讨论⌊n2y⌋\lfloor \frac{n}{2^y} \rfloor⌊2yn​⌋和⌊n2y+1⌋\lfloor\frac{n}{2^{y+1}}\rfloor⌊2y+1n​⌋的奇偶性,还有他们之间奇数个数和⌊n2y+2⌋\lfloor\frac{n}{2^{y+2}}\rfloor⌊2y+2n​⌋之间的关系……

的确可以讨论出来,并且也是可以实现的,但是……很复杂啊……

最后我还是没有吧这种方法打上去。


正解

正解的方法要简单多了。

一条链中的数字都可以表示成2kx2^kx2kx的形式。

第一项时k=0k=0k=0,第mmm项时k=m−1k=m-1k=m−1。所以如果可以放一层,那么就要满足2m−1x≤n2^{m-1}x\leq n2m−1x≤n。

然后我们再从左到右,类似地继续来。

这时第一项时k=mk=mk=m,第mmm项时k=2m−1k=2m-1k=2m−1,那么就要满足22m−1x≤n2^{2m-1}x\leq n22m−1x≤n

因此可以这么做:

1、先将nnn变成⌊n2m−1⌋\lfloor\frac{n}{2^{m-1}}\rfloor⌊2m−1n​⌋。

2、答案加上111到nnn之间奇数个数,也就是⌊n2⌋+nmod&ThinSpace;&ThinSpace;2\lfloor\frac{n}{2}\rfloor+n \mod 2⌊2n​⌋+nmod2。

3、n=⌊n2m⌋n=\lfloor\frac{n}{2^m}\rfloorn=⌊2mn​⌋,然后回到第2步。

为什么第一次是m−1m-1m−1,第二次是mmm呢?不解释,手推一下就好。

这样做可以将一些能放多层的链的贡献累加起来,代码实现比较简单,时间也比较优秀。


代码

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cassert>
#define BIT 12
#define BITS 1000000000000ll
struct Bigint{
long long v[2001];
};
Bigint n;
int m;
Bigint ans;
inline void read(Bigint &x){
static char str[100001];
scanf("%s",str);
int len=strlen(str);
memset(x.v,0,sizeof x.v);
for (int i=len-1;i>=0;i-=BIT){
x.v[0]++;
long long w=1;
for (int j=0;j<BIT && i-j>=0;++j,w*=10)
x.v[x.v[0]]+=(str[i-j]-'0')*w;
}
}
inline void write(Bigint &x){
printf("%lld",x.v[x.v[0]]);
for (int i=x.v[0]-1;i>=1;--i)
printf("%012lld",x.v[i]);
printf("\n");
}
inline void operator/=(Bigint &x,int y){
long long mo=0;
for (int i=x.v[0];i>=1;--i){
x.v[i]=x.v[i]+mo*BITS;
mo=x.v[i]%y;
x.v[i]/=y;
}
while (x.v[0] && !x.v[x.v[0]])
x.v[0]--;
if (!x.v[0])
x.v[0]=1;
}
inline void calc(){//计算ans
ans.v[1]+=n.v[1]&1;
n/=2;
ans.v[0]=max(ans.v[0],n.v[0]);
for (int i=1;i<=ans.v[0];++i){
ans.v[i]+=n.v[i];
ans.v[i+1]+=ans.v[i]/BITS;
ans.v[i]%=BITS;
}
if (ans.v[ans.v[0]+1])
ans.v[0]++;
}
int main(){
int T;
scanf("%d",&T);
while (T--){
read(n);
scanf("%d",&m);
memset(ans.v,0,sizeof ans.v);
n/=1<<m-1;
while (!(n.v[0]==1 && n.v[1]==0)){//n不为0时
calc();
n/=1<<m-1;//在calc()操作中,n=n/2
}
write(ans);
}
return 0;
}

总结

当自己想得很复杂的时候,应该考虑一下,这是否是恰当的解法……

JZOJ[3771] 【NOI2015模拟8.15】小 Z 的烦恼的更多相关文章

  1. 【20170920校内模拟赛】小Z爱学习

    所有题目开启-O2优化,开大栈空间,评测机效率为4亿左右. T1 小 Z 学数学(math) Description ​ 要说小 Z 最不擅长的学科,那一定就是数学了.这不,他最近正在学习加法运算.老 ...

  2. 【0521模拟赛】小Z爱数学

    题目描述 小Z想求F(n,k),F(n,k)表示n的所有因数pi中,满足n/pi <= k 的和. 小Z发现还是很水,所以他决定加大难度. 求 小Z还准备了很多个询问.现在你来解决一下吧. 输入 ...

  3. 【0521模拟赛】小Z爱划水

    题目描述 小Z和其它机房同学都面临一个艰难的抉择,那就是 要不要划水? 每个人都有自己的一个意见,有的人想做题,有的人想划水. 当然,每个人只能选择一个事情做.如果一个人做的事情和他想做的不同,那么他 ...

  4. [JZOJ 5906] [NOIP2018模拟10.15] 传送门 解题报告(树形DP)

    题目链接: https://jzoj.net/senior/#contest/show/2528/2 题目: 8102年,Normalgod在GLaDOS的帮助下,研制出了传送枪.但GLaDOS想把传 ...

  5. 2017-10-5模拟赛T2 小Z爱排序(sorting.*)

    Description Solution 比赛时找到了规律,但是没有证出来……(当然最后还是AC了……) 显然没有被操作的数在排好序的序列中一定是连续的一段. 所以,没有被操作的数一定从左到右连续地递 ...

  6. [JZOJ 5905] [NOIP2018模拟10.15] 黑暗之魂(darksoul) 解题报告 (拓扑排序+单调队列+无向图基环树)

    题目链接: http://172.16.0.132/senior/#main/show/5905 题目: oi_juruo热爱一款名叫黑暗之魂的游戏.在这个游戏中玩家要操纵一名有 点生命值的无火的余灰 ...

  7. 【20170521校内模拟赛】热爱生活的小Z

    学长FallDream所出的模拟赛,个人感觉题目难度还是比较适中的,难度在提高+左右,可能比较接近弱省省选,总体来讲试题考查范围较广,个人认为还是很不错的. 所有试题如无特殊声明,开启-O2优化,时限 ...

  8. CONTEST36 小Z的模拟赛(2)

    A.小Z的可恶路障 题目:http://www.luogu.org/problem/show?pid=U126 题解:暴力也可以过吧.我为了保险先求了一次最短路,然后枚举这条最短路上的所有边... 代 ...

  9. 2019.2.25 模拟赛T1【集训队作业2018】小Z的礼物

    T1: [集训队作业2018]小Z的礼物 我们发现我们要求的是覆盖所有集合里的元素的期望时间. 设\(t_{i,j}\)表示第一次覆盖第i行第j列的格子的时间,我们要求的是\(max\{ALL\}\) ...

随机推荐

  1. 用python, PIL在图像上添加文字(可以控制,调节为水印等)

    最近想在图像上,添加想要的文字,首先想到的是matplotlib,但是这个更加倾向于画图(柱状图,折线图之类) opencv这个库肯定也行,但是为了和我现有程序连接在一起,我选择了PIL 其中字体的设 ...

  2. KNN 实战

    KNN算法很简单,大致的工作原理是:给定训练数据样本和标签,对于某测试的一个样本数据,选择距离其最近的k个训练样本,这k个训练样本中所属类别最多的类即为该测试样本的预测标签.简称kNN.通常k是不大于 ...

  3. 关于strtok函数

    函数原型: char *strtok(char * strToken, const char *strDelimit) 参数说明: strToken:源字符串,即待分割的串 strDelimit:st ...

  4. Eclipse指定JDK版本

    Eclipse有好多版本,同时又分32位和64位,要使用相对应的版本和一样位数的JDK,Eclipse才能正常运行. 对应不上时,Eclipse 甚至不能正常启动.报错:“Failed to load ...

  5. CSIC_716_20191125【面向对象编程--类以及类的实例化】

    面向对象编程:是一种编程思想 对象的定义:特征与功能的集合体 优点:可扩展性强 缺点:编程复杂度高,难度偏大 类的定义:一系列对象之间相同特征与技能的结合体 调用类的时候(实例化是时候),发生的事情: ...

  6. undertow服务器

    参考地址:http://undertow.io/undertow-docs/undertow-docs-1.3.0/index.html 1.引入相关jar <dependencies> ...

  7. jQuery FormData使用方法

    FormData的主要用途 将form表单元素的name与value进行组合,实现表单数据的序列化,从而减少表单元素的拼接,提高工作效率. 异步上传文件 注:FormData 对象的字段类型可以是 B ...

  8. 「题解」:[loj2763][JOI2013]现代豪宅

    问题 A: 现代豪宅 时间限制: 1 Sec  内存限制: 256 MB 题面 题目描述 (题目译自 $JOI 2013 Final T3$「現代的な屋敷」) 你在某个很大的豪宅里迷路了.这个豪宅由东 ...

  9. linux下常见的包安装方式

    linux下常见的包安装方式 一.总结 一句话总结: rpm包安装 tar.gz源代码包安装 yum方式安装rpm包 bin文件安装 1.yum是什么? 安装所有依赖的软件包 Yum(全称为 Yell ...

  10. PAT甲级——A1132 Cut Integer

    Cutting an integer means to cut a K digits lone integer Z into two integers of (K/2) digits long int ...