题目

描述

题目大意

有从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. oracle 管理表空间

    表空间:是oracle数据库中最大的逻辑存储结构,与操作系统中的数据文件相对应,用于存储数据库中用户创建的所有内容 表空间>数据文件 4.1创建一个永久性表空间myspace create ta ...

  2. neo4j 基本概念和Cypher语句总结

    下面是一个介绍基本概念的例子,参考链接Graph database concepts: (1) Nodes(节点) 图谱的基本单位主要是节点和关系,他们都可以包含属性,一个节点就是一行数据,一个关系也 ...

  3. webservice - 使用JAX-WS注解的方式快速搭建服务端和客户端

    1.Define the interface import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebRe ...

  4. css---2D变形

    1.transfrom:rotate(360deg); 用前要加transition: 2s;                      deg重点 transform:rotate(angle); ...

  5. Java 多线程 - ThreadLocal

    ref: https://www.cnblogs.com/chengxiao/p/6152824.html

  6. hdu6607 min25筛+杜教筛+伯努利数求k次方前缀和

    推导过程类似https://www.cnblogs.com/acjiumeng/p/9742073.html 前面部分min25筛,后面部分杜教筛,预处理min25筛需要伯努利数 //#pragma ...

  7. RocketMQ在linux下安装部署

    本博客以当前RocketMQ最新版介绍:v4.4.0 环境要求 64位JDK 1.8+; Maven 3.2.x; // 源码编译时需要用到 二进制文件安装 下载二进制文件:http://mirror ...

  8. python支付宝页面扫码支付

    一.介绍 基于网上一个支付宝pay.py封装了支付宝API的文件进行的,以下代码只支持网页扫码支付,手机端会提示调用支付宝支付 #pay文件代码 from datetime import dateti ...

  9. 机器学习 101 Mahout 简介 建立一个推荐引擎 使用 Mahout 实现集群 使用 Mahout 实现内容分类 结束语 下载资源

      机器学习 101 Mahout 简介 建立一个推荐引擎 使用 Mahout 实现集群 使用 Mahout 实现内容分类 结束语 下载资源 相关主题   在信息时代,公司和个人的成功越来越依赖于迅速 ...

  10. 二分查找总结及部分Lintcode题目分析 3

    Search in rotated sorted array,题目中也给出了相应的例子,就是在sorted array某个节点发生了翻转(ie.0 1 2 4 5 6 7 might become 4 ...