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; 当 ...
随机推荐
- 图解堆算法、链表、栈与队列(Mark)
原文地址: 图解堆算法.链表.栈与队列(多图预警) 堆(heap),是一类特殊的数据结构的统称.它通常被看作一棵树的数组对象.在队列中,调度程序反复提取队列中的第一个作业并运行,因为实际情况中某些时间 ...
- 博弈SG函数
转自:Sprague-Grundy Function-SG函数--博弈论(3) 公平游戏的Sprague-Grundy定理 公平游戏是一种双人游戏,在游戏中双方都有完整的信息,没有牵涉,任何状态的合法 ...
- Windows 下Node.js开发环境配置
第一步:安装VirtualBox(以管理员身份安装) 1.安装完成后,打开VirtualBox,点击“新建”按钮,输入信息,“下一步”(名称可任意) 2.设置内存为1024MB,“下一步”—>“ ...
- iostat命令简单使用
1.iostat使用范围 iostat命令可以生成3种类型的报告: (1)CPU使用情况的报告 (2)设备使用情况的报告 (3)网络文件系统(NFS)使用情况的报告 2.每种报告的格式说明 关于CPU ...
- mysql导出数据或结构
导出整个数据库结构和数据 $ mysqldump -h localhost -uroot -p123456 database > dump.sql 导出单个数据表结构和数据 $ mysqldum ...
- selenium java 封装
1.简单介绍 1)展示如何封装selenium的api,使其符合我们的使用需求: 2)展示如何使用page object模式写selenium脚本: 3)展示如何即时查找元素,用以操作ajax页面: ...
- error in static/js/xxx.js from UglifyJs Unpected token: punc() [static/js/xxx.js]
出现问题 使用vue+element-ui+webpack开发项目时,Jenkins构建出现报错error in static/js/xxx.js from UglifyJs Unpected tok ...
- border --- 透明边框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Data Structure Graph: strong connectivity
如果为undirected graph就是dfs或者bfs,如果都能visit则为连通O(V+E). 如果为directed graph就先dfs或者bfs,再reverse direct,再dfs或 ...
- 【leetcode刷题笔记】Simplify Path
Given an absolute path for a file (Unix-style), simplify it. For example,path = "/home/", ...