题目链接: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. centos7.0 tomcat9.0 ip访问 manager

    版本:Tomcat 9.0 问题:新安装的tomcat,用其他机器访问tomcat的Server Status.Manager App.Host Manager三个页面均显示403(本机访问没有问题) ...

  2. 附004.Kubernetes Dashboard简介及使用

    一 Kubernetes dashboard简介 1.1 Web UI简介 dashboard是基于Web的Kubernetes用户界面.可以使用dashboard将容器化应用程序部署到Kuberne ...

  3. Python小白的发展之路之Python基础(三)【函数简介】

    目录: 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 4.嵌套函数 5.递归 6.匿名函数 7.函数式编程介绍 8.高阶函数 9.内置函数 1. 函数基本语法及特性 首先我们明确函数是 ...

  4. [CTSC2001]1378 选课

      1378 选课 题目描述 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<300)门的选修课程,每个学生可选课程的数量M是给定的.学生选修了这 ...

  5. z-index随笔

    z-index这个css属性是用来控制层级的,但是它的表现有点奇怪,这里做下记录. 假如有ABC三层,都没设置z-index时,是按dom节点顺序来控制层级. 此时如果B元素下有个元素D,设置了z-i ...

  6. Mybatis的动态SQL实现

    一.动态SQL简介 MyBatis的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不能忘了必要的 ...

  7. HDFS上传机制

  8. SpringMVC拦截器实现登录认证

    项目结构如图: 需要的jar:有springMVC配置需要的jar和jstl需要的jar SpringMVC包的作用说明: aopalliance.jar:这个包是AOP联盟的API包,里面包含了针对 ...

  9. 【python】-- Socket接收大数据

    Socket接收大数据 上一篇博客中的简单ssh实例,就是说当服务器发送至客户端的数据,大于客户端设置的数据,则就会把数据服务端发过来的数据剩余数据存在IO缓冲区中,这样就会造成我们想要获取数据的完整 ...

  10. JDBC详解2

    day18总结 今日思维导图: 今日内容 事务 连接池 ThreadLocal BaseServlet自定义Servlet父类(只要求会用,不要求会写) DBUtils à commons-dbuti ...