ACM学习历程—HDU5587 Array(数学 && 二分 && 记忆化 || 数位DP)(BestCoder Round #64 (div.2) 1003)
题目链接: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)的更多相关文章
- (BestCoder Round #64 (div.2))Array
BestCoder Round #64 (div.2) Array 问题描述 Vicky是个热爱数学的魔法师,拥有复制创造的能力. 一开始他拥有一个数列{1}.每过一天,他将他当天的数列复制一遍,放在 ...
- ACM学习历程—SNNUOJ1215 矩阵2(二分 && dfs)
http://219.244.176.199/JudgeOnline/problem.php?id=1215 这是这次微软和百度实习面试的一道题,题目大意就是:有一个n*m的矩阵,已知它每一行都是不严 ...
- ACM学习历程—SNNUOJ1214 矩阵1(二分)
题目链接:http://219.244.176.199/JudgeOnline/problem.php?id=1214 这是这次微软实习面试的一道题,题目大意就是:有一个n*m的矩阵,已知它每一行都是 ...
- ACM学习历程—HDU5586 Sum(动态规划)(BestCoder Round #64 (div.2) 1002)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5586 题目大意就是把一段序列里面的数替换成f(x),然后让总和最大. 首先可以计算出初始的总和,以及每 ...
- ACM学习历程—HDU5585 Numbers(数论 || 大数)(BestCoder Round #64 (div.2) 1001)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5585 题目大意就是求大数是否能被2,3,5整除. 我直接上了Java大数,不过可以对末尾来判断2和5, ...
- ACM学习历程—CodeForces 176B Word Cut(字符串匹配 && dp && 递推)
Description Let's consider one interesting word game. In this game you should transform one word int ...
- hdu5587 BestCoder Round #64 (div.2)
问题描述 Vicky是个热爱数学的魔法师,拥有复制创造的能力. 一开始他拥有一个数列{1}.每过一天,他将他当天的数列复制一遍,放在数列尾,并在两个数列间用0隔开.Vicky想做些改变,于是他将当天新 ...
- 【记忆化搜索】Codeforces Round #295 (Div. 2) B - Two Buttons
题意:给你一个数字n,有两种操作:减1或乘2,问最多经过几次操作能变成m: 随后发篇随笔普及下memset函数的初始化问题.自己也是涨了好多姿势. 代码 #include<iostream> ...
- 记忆化搜索(DP+DFS) URAL 1183 Brackets Sequence
题目传送门 /* 记忆化搜索(DP+DFS):dp[i][j] 表示第i到第j个字符,最少要加多少个括号 dp[x][x] = 1 一定要加一个括号:dp[x][y] = 0, x > y; 当 ...
随机推荐
- IOS发送带附件的邮件
本文转载至 http://blog.csdn.net/zltianhen/article/details/7693810 1.加入邮箱的框架 #import <MessageUI/MFMail ...
- .net EF监控 MiniProfiler
1.从NuGet上下载所需要的包:MiniProfiler.mvc,MiniProfiler,MiniProfiler.ef 2.Global.asax 加入 protected void Appli ...
- 信息搜集之google语法
总结的比较全,无耻的转了.D: http://blog.csdn.net/chaosa/article/details/1828301 说起Google,可谓无人不知无人不晓.作为世界第一的搜索引擎, ...
- 九度OJ 1343:城际公路网 (最小生成树)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:445 解决:178 题目描述: 为了加快城市之间的通行和物资流动速度,A国政府决定在其境内的N个大中型城市之间,增加修建K条公路.已知这N个 ...
- picasso设置背景图片
compile'com.squareup.picasso:picasso:2.5.2' String url = "http://192.168.191.1:8080/b"+(i+ ...
- 【Prometheus】第二篇---基本查询语法
这几天忙着开发别的项目,今天抽空写一下Prometheus的查询语法 1,查看指标 直接输入指标名字就行了,grafana会自动补全 2,查看某个指标的使用率,比如cpu使用率 用到rate函数,ra ...
- python3 生成随即激活码
import string import random #激活码中的字符和数字 field = string.ascii_letters + string.digits #获得四个字母和数字的随即组合 ...
- composer 更新国内镜像地址
composer config -g repo.packagist composer https://packagist.phpcomposer.com
- python核心编程3-13
3.13: 添加新功能. 将你上一个问题改造好的readNwriteTextFiles.py 增加一个新功能: 允许用户编辑一个已经存在的文本文件. 你可以使用任何方式,无论是一次编辑一行,还是一次编 ...
- CodeForces 292D Connected Components (并查集+YY)
很有意思的一道并查集 题意:给你n个点(<=500个),m条边(<=10000),q(<=20000)个询问.对每个询问的两个值xi yi,表示在从m条边内删除[xi,yi]的边后 ...