ZOJ 3872--解题报告
题目相关:
3872相关链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5520
Edward拥有一组数列. 其定义了Beauty数: 连续子串的和(重复的项只计算一次). 比如子串: 2, 3, 3. 则总和为beauty=2+3= 5 (数值3只计算一次).
目标: 求一组数列中, 所有Beauty数的总和.
思路分析:
• 评估数据:
数据规模: 数列的长度为N (1 <= N <= 100000)
数值范围: 成员都是正整数, 且大小不大于1000000.
由此可得, 子串个数为N*(N-1)/2, 而最终的总数最大范围为 N*N*M = 10^5 * 10^5 * 10^6 = 10^16, 超过4位int/long范围, 尚在8位long long的表示范围内.
• 思路权衡
采用暴力的方式去解决, 枚举每个子串, 显然不可行. 就算子串的和计算为O(1), 由于子串个数N*(N-1)/2的数据规模10^10, 显然不行.
关于计数/累计和的问题时, 往往可以采取动态规划的方式来简化这个问题.
设定opt[k]表示序列以第k个元素结尾的所有子串和, val[k]为数组的第k个元素数值.
如果不考虑重复数据不得累加的问题, 则递进公式为:
opt[k] = opt[k - 1] + delta(k) * val[k] = opt[k - 1] + k * val[k]
opt[k]在opt[k-1]对应的所有子串基础上, 尾部添加val[k]项组成新子串. 总共添加k次. 然而由于重复数字只计算一次的限制, 该公式需要修正.
引入索引映射idx, 其key为数值, value表示该数值最后出现的索引位置.
修正的核心为:
delta(k) = 新子串数 - 忽略次数 = k - idx[val[k]]
注: idx[val[k]]为val[k]最后出现的索引位置, 在这之前的子串因该数值已出现过, 视为忽略.
于是递进公式演变为:
opt[k] = opt[k - 1] + delta(k) * val[k] = opt[k - 1] + (k - idx[val[k]]) * val[k]; 最后结果为:
result = opt[1] + opt[2] + ... + opt[n]
这样总得时间复杂度为O(N).
AC代码:
#include <cstdio>
#include <map> typedef long long LL; int main()
{ int kase;
scanf("%d", &kase);
while ( kase-- > 0 ) {
int n;
scanf("%d", &n); std::map<int, int> kbmap;
LL opt_sum = 0, total_sum = 0;
int val;
for ( int i = 1; i <= n; i++ ) {
scanf("%d", &val);
opt_sum = opt_sum + (i - kbmap[val]) * val;
total_sum += opt_sum;
kbmap[val] = i;
} printf("%ld\n", total_sum); } return 0;
}
ZOJ 3872--解题报告的更多相关文章
- ZOJ 1093 Monkey and Banana (LIS)解题报告
ZOJ 1093 Monkey and Banana (LIS)解题报告 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid= ...
- zoj 2313 Chinese Girls' Amusement 解题报告
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1313 题目意思:有 N 个人(编号依次为1~N)围成一个圆圈,要求求 ...
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
- 二模13day1解题报告
二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...
- BZOJ 1051 最受欢迎的牛 解题报告
题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4438 Solved: 2353[S ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1035 火车停留解题报告
本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- 习题:codevs 1519 过路费 解题报告
今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...
- NOIP2016提高组解题报告
NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合
随机推荐
- (DFS)hdoj1010-Tempter of the Bone
#include<cstdio> #include<cmath> #include<stdlib.h> ][]={{,},{,-},{,},{-,}},escape ...
- 第46套题【STL】【贪心】【递推】【BFS 图】
已经有四套题没有写博客了.今天改的比较快,就有时间写.今天这套题是用的图片的形式,传上来不好看,就自己描述吧. 第一题:单词分类 题目大意:有n个单词(n<=10000),如果两个单词中每个字母 ...
- C++指针详解(二)
指针是C/C++编程中的重要概念之一,也是最容易产生困惑并导致程序出错的问题之一.利用指针编程可以表示各种数据结构,通过指针可使用主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯:指针能 ...
- [转]android Intent机制详解
转自:http://blog.csdn.net/t12x3456/article/details/7688154 1.什么是Intent Intent是一种运行时绑定(run-time binding ...
- SharePoint 2013 开发——构建工作流开发环境
博客地址:http://blog.csdn.net/FoxDave 本篇我们来讲述一下如何搭建SharePoint 2013工作流开发环境. Windows Azure Workflow作为单独的可下 ...
- Hibernate xml格式和anno格式 mappedby
xml配置的时候多对一 一对多的外键可以配置一样,但是anno不太好弄,多这边配完了,一那边用个mappedby"“自己在对方的属性”就可以,不然要建一张中间表.xml的mappedby因为 ...
- 【python】import 模块、包、第三方模块
xx.py文件,称为模块(module),把不同模块归整到一起的文件夹,叫做包(package) 不同包下的模块可以重名,但是都不能和系统内建模块重名 包里面一定要有个__init__.py文件,否则 ...
- innerHTML..innerText..textContent
/* * innerText和textContent 都是设置文字内容的,如果设置的内容当中有标签,也会直接的以文本的方式显示(标签的<>都会按照转义的方式进行解析) * innerTex ...
- java,android获取系统当前时间
SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss ");Date curDate = ...
- scanf和scanfs的区别
scanf()函数是标准C中提供的标准输入函数,用以用户输入数据 scanf_s()函数是Microsoft公司VS开发工具提供的一个功能相同的安全标准输入函数,从vc++2005开始,VS系统提供了 ...