hiho 挑战赛16 B 王胖浩与环
2015-11-04 21:21
253 查看
因数,前缀和
题意:
给你一个循环数组,你要将它截成k段,然后每段有一个区间和,所有的区间和求gcd,就是优美程度,你要使得优美程度最大。k不是输入的,而是你要输出截1段,2段...n段的最优值
数据范围:
n<=2000,ai<=5*10^7
思路:
我算了一下,暴力dp要O(n4)...
注意到,这个优美程度肯定是数组所有元素的和的因子(这个不难证明),那么我们可以把问题反转过来考虑,考虑要截出优美程度为因子x,最多能截多少段。
这里有个很好的性质就是,因子x能截y段,那么就肯定能截y-1段,y-2段...因为你可以把其中相邻的两段合起来,这样它们的区间和还是会整除x的
从头到尾地扫,维护sum,当sum能整除x就截。由于是循环数组,这样的话就要枚举开头去截得到的所有答案求个max。这样的话复杂度就是O(n2*d),d是sum的因子数量。由于sum是longlong范围的,因此会出现有些数因子十分多,d就不是常数或者logn这么简单了
我们要优化掉枚举开头这个东西,有一个很重要的结论,区间和整除,就是前缀和同余!因此我们只需要求出前缀和,然后把它们分组,按模因子x的余数分组。然后最大的那个组的size就是因子x的最多能截的段数。
注意到余数可能是很大的,因此不能直接开个数组记录,要哈希一下,或者直接用个map。由于前缀和最多才2k个,因此加个log也没所谓。
我们把每个因子得到的答案都保存下来,输出截k段的时候,我们直接遍历所有因子,然后找截的最大段数>=k的并且值最大的因子输出。最后复杂度是O(nlogn*d)
注意一点,因子越小不意味着能截更多的段数,所以最后那步是遍历所有因子而不是二分什么的
总结:答案肯定是数组和的因子,把问题反转,求每个因子最多能截多少段
题意:
给你一个循环数组,你要将它截成k段,然后每段有一个区间和,所有的区间和求gcd,就是优美程度,你要使得优美程度最大。k不是输入的,而是你要输出截1段,2段...n段的最优值
数据范围:
n<=2000,ai<=5*10^7
思路:
我算了一下,暴力dp要O(n4)...
注意到,这个优美程度肯定是数组所有元素的和的因子(这个不难证明),那么我们可以把问题反转过来考虑,考虑要截出优美程度为因子x,最多能截多少段。
这里有个很好的性质就是,因子x能截y段,那么就肯定能截y-1段,y-2段...因为你可以把其中相邻的两段合起来,这样它们的区间和还是会整除x的
从头到尾地扫,维护sum,当sum能整除x就截。由于是循环数组,这样的话就要枚举开头去截得到的所有答案求个max。这样的话复杂度就是O(n2*d),d是sum的因子数量。由于sum是longlong范围的,因此会出现有些数因子十分多,d就不是常数或者logn这么简单了
我们要优化掉枚举开头这个东西,有一个很重要的结论,区间和整除,就是前缀和同余!因此我们只需要求出前缀和,然后把它们分组,按模因子x的余数分组。然后最大的那个组的size就是因子x的最多能截的段数。
注意到余数可能是很大的,因此不能直接开个数组记录,要哈希一下,或者直接用个map。由于前缀和最多才2k个,因此加个log也没所谓。
我们把每个因子得到的答案都保存下来,输出截k段的时候,我们直接遍历所有因子,然后找截的最大段数>=k的并且值最大的因子输出。最后复杂度是O(nlogn*d)
注意一点,因子越小不意味着能截更多的段数,所以最后那步是遍历所有因子而不是二分什么的
总结:答案肯定是数组和的因子,把问题反转,求每个因子最多能截多少段
相关文章推荐
- #1094 : Lost in the City
- hiho 挑战赛16 A.王胖浩与三角形
- 【hiho一下】第一周 最长回文子串
- 【hiho一下】第二周 Trie树
- 【hiho一下】第三周 KMP算法
- 【hiho一下】第五周 数字三角形
- hihocoder 状态压缩二
- #1051 : 补提交卡
- [hihoCoder]#1325 : 平衡树·Treap(平衡树)
- hiho#1039 : 字符消除,题解
- hihoCoder--1039:字符消除
- hiho 1228 Mission Impossible 6
- 智力竞赛(hiho145周)
- 后缀自动机学习笔记1(hiho127周)
- Eular质数筛法
- [Hiho]1015-KMP算法
- Disk Storage
- hihoCoder:1039字符串消除(当你找不到自己错在哪里了,可以来我这里看一看)
- hiho #1094 : Lost in the City
- hiho #1082 : 然而沼跃鱼早就看穿了一切