博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Maximum Subarray Sum
阅读量:6036 次
发布时间:2019-06-20

本文共 1260 字,大约阅读时间需要 4 分钟。

题意

给你一个大小为N的数组和另外一个整数M。你的目标是找到每个子数组的和对M取余数的最大值。子数组是指原数组的任意连续元素的子集。

分析

求出前缀和,问题变成了O(n*n)复杂度的问题,但是仍然不能解决问题。

设prefix为前缀和,设i < j,一般都是通过算sum = prefix[j] - prefix[i]求和的最大值,但是本题中有取模,要求sum最大。

第一种情况:如果prefix[j] > prefix[i],sum < prefix[j],这种情况就不需要考虑了。

第二种情况:prefix[j] < prefix[i],又i < j,那么prefix[j]是取模后得到的值,此时sum = prefix[j] + m - prefix[i],要sum尽可能的大,则要求prefix[i]尽可能的小,而prefix[i] > prefix[j],所以每次要
前面出现过的前缀和里找比它大一点的值,这里就想到了C++里的set,有序的集合,set.upper_bound二分查找,并插入前缀和,复杂度O(nlogn)。

code

#include 
using namespace std;typedef long long ll;const int MAXN = 1e5 + 5;ll a[MAXN];int main(){ ios::sync_with_stdio(0); cin.tie(0); int T, n; ll m; cin >> T; while(T--) { cin >> n >> m; for(int i = 0; i < n; i++) { ll x; cin >> x; if(i == 0) a[0] = x % m; else a[i] = (a[i - 1] % m + x) % m; } set
st; ll mx = 0; for(int i = 0; i < n; i++) { set
::iterator x = st.upper_bound(a[i]); if(x != st.end()) mx = max(mx, a[i] + m - *x); mx = max(mx, a[i]); st.insert(a[i]); } cout << mx << endl; } return 0;}

转载于:https://www.cnblogs.com/ftae/p/6791400.html

你可能感兴趣的文章
我所经历的前端开发变化
查看>>
fio测试nvme性能
查看>>
node常用模块---path
查看>>
WebSocket于HTTP 、WebSocket与Socket的区别
查看>>
xpath与css的区别
查看>>
Java ClassLoader分析
查看>>
SharePoint 2010 上下左右求和
查看>>
J_Knight_ iOS 高级面试题 实战题解答以及一些扩展性链接
查看>>
使用php mongodb扩展时比较需要注意的事项
查看>>
AMQP的安装
查看>>
C语言小知识,摘自o'reilly著C程序设计新思维,人民邮电出版社
查看>>
深入详解SQL中的Null
查看>>
《转》完美解决微信video视频隐藏控件和内联播放问题
查看>>
AngularJs工具方法
查看>>
Django的模板系统
查看>>
jQuery自动触发事件
查看>>
跑步书籍推荐 --- 跑步指南
查看>>
1199 Problem B: 大小关系
查看>>
Elasticsearch 优化
查看>>
20145237《Java程序设计》第一周学习总结
查看>>