题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5587

题目大意就是初始有一个1,然后每次操作都是先在序列后面添加一个0,然后把原序列添加到0后面,然后从0到末尾,每一个都加上1。

例如:a0, a1, a2 => a0, a1, a2, 1, a0+1, a1+1, a2+1

题解中是这么说的:“

其实Ai为i二进制中1的个数。每次变化A{k+2^i}=A{k}+1,(k<2^​i​​)不产生进位,二进制1的个数加1。然后数位dp统计前m个数二进制1的个数,计算每一位对答案的贡献。只需考虑该位填1,其高位与低位的种数即可。

不过我没有想到这个。

我写了几次变换后,发现:

对最前面添加一个0,

于是每次变换长度都变成两倍,而且前后序列每一个对应差值为1。

不过这样前后二分显然对于m+1是2的次方有要求。

但是对于每2个组成一组,那么发现,至少每次变换都是以2的倍数个变换的。

也就是说单看i%2== 1的那些数ai,发现他们组成的序列变换和原序列一模一样。

i%2== 0的同理,不过需要在每一个数的基础上加上1。

然后对于s(n),自然可以由它前面i%2 == 1, i%2 == 0的两组序列构成

于是就变成了s(n) = s(n/2)+s(n/2)+n/2 or s(n/2+1)+s(n/2)+n/2(取决于n%2)

这样的话就能二分下去了,不过需要记忆化,这里采用了map进行记忆化。

不过比赛的时候,我写的是四个为一组。由于上面的n/2和n/2+1只有当大量出现n%2等于0了才能每次截掉一半。但是如果四个一组的话,每次长度变成1/4,但是最多生成n/4和n/4+1。不过这两种在不记忆化的情况下都会T。

不过用map记忆化后,我怕会MLE,本地测了好几组数据,都没有占很大内存。

代码:(二分)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long using namespace std; LL m;
map<LL, LL> s; LL dfs(LL n)
{
if (n == ) return ;
if (n == ) return ;
LL ans, t1 = , t2;
if (n%)
{
if (s[n/+] == )
{
t1 = dfs(n/+);
s[n/+] = t1;
}
else t1 = s[n/+];
}
if (s[n/] == )
{
t2 = dfs(n/);
s[n/] = t2;
}
else t2 = s[n/]; ans = (n%)*t1+(-n%)*t2;
ans += n/;
return ans;
} int main()
{
//freopen("test.in", "r", stdin);
int T;
scanf("%d", &T);
for (int times = ; times <= T; ++times)
{
scanf("%I64d", &m);
LL ans;
ans = dfs(m+);
printf("%I64d\n", ans);
}
return ;
}

代码:(四分)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long using namespace std; LL m;
map<LL, LL> s; LL dfs(LL n)
{
if (n == ) return ;
if (n == ) return ;
if (n == ) return ;
if (n == ) return ;
LL ans, t1 = , t2;
if (n%)
{
if (s[n/+] == )
{
t1 = dfs(n/+);
s[n/+] = t1;
}
else t1 = s[n/+];
}
if (s[n/] == )
{
t2 = dfs(n/);
s[n/] = t2;
}
else t2 = s[n/];
ans = (n%)*t1+(-n%)*t2;
ans += n/*;
if (n%) ans += n%-;
return ans;
} int main()
{
//freopen("test.in", "r", stdin);
int T;
scanf("%d", &T);
for (int times = ; times <= T; ++times)
{
//s.clear();
scanf("%I64d", &m);
LL ans;
ans = dfs(m+);
printf("%I64d\n", ans);
}
return ;
}

ACM学习历程—HDU5587 Array(数学 && 二分 && 记忆化 || 数位DP)(BestCoder Round #64 (div.2) 1003)的更多相关文章

  1. (BestCoder Round #64 (div.2))Array

    BestCoder Round #64 (div.2) Array 问题描述 Vicky是个热爱数学的魔法师,拥有复制创造的能力. 一开始他拥有一个数列{1}.每过一天,他将他当天的数列复制一遍,放在 ...

  2. ACM学习历程—SNNUOJ1215 矩阵2(二分 && dfs)

    http://219.244.176.199/JudgeOnline/problem.php?id=1215 这是这次微软和百度实习面试的一道题,题目大意就是:有一个n*m的矩阵,已知它每一行都是不严 ...

  3. ACM学习历程—SNNUOJ1214 矩阵1(二分)

    题目链接:http://219.244.176.199/JudgeOnline/problem.php?id=1214 这是这次微软实习面试的一道题,题目大意就是:有一个n*m的矩阵,已知它每一行都是 ...

  4. ACM学习历程—HDU5586 Sum(动态规划)(BestCoder Round #64 (div.2) 1002)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5586 题目大意就是把一段序列里面的数替换成f(x),然后让总和最大. 首先可以计算出初始的总和,以及每 ...

  5. ACM学习历程—HDU5585 Numbers(数论 || 大数)(BestCoder Round #64 (div.2) 1001)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5585 题目大意就是求大数是否能被2,3,5整除. 我直接上了Java大数,不过可以对末尾来判断2和5, ...

  6. ACM学习历程—CodeForces 176B Word Cut(字符串匹配 && dp && 递推)

    Description Let's consider one interesting word game. In this game you should transform one word int ...

  7. hdu5587 BestCoder Round #64 (div.2)

    问题描述 Vicky是个热爱数学的魔法师,拥有复制创造的能力. 一开始他拥有一个数列{1}.每过一天,他将他当天的数列复制一遍,放在数列尾,并在两个数列间用0隔开.Vicky想做些改变,于是他将当天新 ...

  8. 【记忆化搜索】Codeforces Round #295 (Div. 2) B - Two Buttons

    题意:给你一个数字n,有两种操作:减1或乘2,问最多经过几次操作能变成m: 随后发篇随笔普及下memset函数的初始化问题.自己也是涨了好多姿势. 代码 #include<iostream> ...

  9. 记忆化搜索(DP+DFS) URAL 1183 Brackets Sequence

    题目传送门 /* 记忆化搜索(DP+DFS):dp[i][j] 表示第i到第j个字符,最少要加多少个括号 dp[x][x] = 1 一定要加一个括号:dp[x][y] = 0, x > y; 当 ...

随机推荐

  1. 【BZOJ4069】[Apio2015]巴厘岛的雕塑 按位贪心+DP

    [BZOJ4069][Apio2015]巴厘岛的雕塑 Description 印尼巴厘岛的公路上有许多的雕塑,我们来关注它的一条主干道. 在这条主干道上一共有 N 座雕塑,为方便起见,我们把这些雕塑从 ...

  2. 摘要: CentOS 6.5搭建Redis3.2.8伪分布式集群

    from https://my.oschina.net/ososchina/blog/856678     摘要: CentOS 6.5搭建Redis3.2.8伪分布式集群 前言 最近在服务器上搭建了 ...

  3. js的new到底干了啥 -

    javascript通过new操作符构建一个对象的步骤 <Javascript高级程序设计>的解释: 创建一个对象 将构造函数的作用域赋给新对象(把新对象作为构造函数的调用上下文,也就是t ...

  4. 20179209《Linux内核原理与分析》安全类实验答疑

    实验一 题目 Nmap 配合 Metasploit 进行端口扫描 问题 Nmap怎么配合Metasploit进行端口扫描? 回答 这里的Nmap配合Metasploit进行端口扫描是指在Metaspl ...

  5. 【学员管理系统】0x04 数据库连接优化

    [学员管理系统]0x04  pymysql数据库连接优化 写在前面 项目详细需求参见:Django项目之[学员管理系统] 优化实现 把操作封装成函数 我们之前使用pymysql操作数据库的操作都是写死 ...

  6. 我的Android进阶之旅------> Android应用升级构想和要点总结

    广大博友,看过后帮忙顶顶,谢谢大家!!! 转载请注明: http://blog.csdn.net/richway2010/article/details/6408258 [博主:各位博友,网友们,大家 ...

  7. 如何从统计中批量获取BD搜索关键词及对应的入口页面?

    前面我们介绍了通过cnzz的访问明细获取到搜索关键词及对应的入口页面,但是从BD搜索进来的关键词无法完整显示,只能呈现一些bd图片搜索的关键词,这是因为百度宣布从去年5月开始逐渐取消了referer关 ...

  8. IntelliJ IDEA(2017)安装和破解(转发)

    IntelliJ IDEA(2017)安装和破解 IDEA 全称 IntelliJ IDEA,是Java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一,尤其在智能代码助手 ...

  9. python基础21 ------python基础之socket编程

    一.C/S架构和B/S架构的简介 略 二.osi七层模型 略 三.socket层 1.如图所示: socket层是存在于应用层和传输层直接抽象出来的一层. 2.socket层是什么? Socket是应 ...

  10. Gem简介

    Rubyems:简称gems是一个用于对rails组建近些年个打包的ruby打包系统,它提供了一个分发ruby程序喝库的标准格式,还提供了一个管理程序包的工具.Rubyems的功能类似于linux下的 ...