51nod 1065 最小正字段和 解决办法:set存前缀和,二分插入和二分查找
2017-10-20 21:18
369 查看
题目:
这题要求大于0的最小字段和,常规O(n)求最大字段和的方法肯定是没法解的。
我的解法是:用sum[i]存前i项的和,也就是前缀和。
这题就变成了求sum[j]-sum[i]的大于0的最小值( j > i )。
我们可以看到直接循环运算量是50000*50000,会超时。
所以我们应该充分利用前缀和的特性。
我们用一个set容器来装sum。
当算到i项时,保证前i-1项已经装入了set中。
我们用二分查找找到第一个比sum[i]小的值,用sum[i]减去这个值来更新答案。
至于二分插入,set容器中插入数据用的就是二分插入。
代码:
这题要求大于0的最小字段和,常规O(n)求最大字段和的方法肯定是没法解的。
我的解法是:用sum[i]存前i项的和,也就是前缀和。
这题就变成了求sum[j]-sum[i]的大于0的最小值( j > i )。
我们可以看到直接循环运算量是50000*50000,会超时。
所以我们应该充分利用前缀和的特性。
我们用一个set容器来装sum。
当算到i项时,保证前i-1项已经装入了set中。
我们用二分查找找到第一个比sum[i]小的值,用sum[i]减去这个值来更新答案。
至于二分插入,set容器中插入数据用的就是二分插入。
代码:
#include <bits\stdc++.h> using namespace std; typedef long long ll; ll sum[50010]; // sum[i]表示 1~(i-1) 项的和 set <ll> s; // 到第i项时,s存的是 sum[1]~sum[i-1] set <ll>::iterator it; //迭代器 int main() { int n; cin >> n; int mn = 2000000000; int key; for(int i = 1;i <= n; i++){ cin >> key; sum[i] = sum[i-1]+key; } s.insert(0); for(int i = 1;i <= n; i++){ // lower_bound返回大于等于sum[i]的最小值 // upper_bound返回大于sum[i]的最小值 it = s.lower_bound(sum[i]); if(it != s.begin()){ it--; //it表示小于sum[i]的最大值 if(sum - *it > 0){ mn = min((ll)mn,sum[i]-*it); } } s.insert(sum[i]); } cout << mn << endl; return 0; }
相关文章推荐
- mysql中设置字段默认为空,插入数据时会提示doesn't have a default value的解决办法
- CMS(新闻发布系统)存放新闻表内容的字段是text,数据过多无法插入,解决办法!
- 51Nod 1065 最小正子段和 前缀和
- 51Nod 1422 沙拉酱前缀 二分查找
- 批量插入Oracle,遇到CLob字段慢的解决办法
- ThinkPHP增加数据库字段后插入数据为空的解决办法
- mysql字段类型为int默认null,插入却显示0的解决办法,参考php代码
- 向ACCESS中的"时间/日期"字段中插入DateTime.Now时出现“标准表达式中数据类型不匹配。”错误的解决办法
- thinkphp5.0.2 多对多模型中插入中间表字段不存在的解决办法
- 51nod 1065 最小正子段和(前缀和)
- phalcon model在插入或更新时会自动验证非空字段的解决办法
- java.util.Date()插入MySQL数据库datetime字段出错的解决办法
- 51nod 1065 最小正字段和
- 向ACCESS中的"时间/日期"字段中插入DateTime.Now时出现“标准表达式中数据类型不匹配。”错误的解决办法
- db2修改表字段后插入数据报《-668》错误解决办法
- jsp向mysql数据库插入中文字段 乱码以及中文空白的解决办法
- 51nod 1065 最小正子段和(最小正字段和)
- 51 nod 1624 取余最长路 思路:前缀和 + STL(set)二分查找
- 解决Mysql数据库插入数据出现问号(?)的解决办法
- excel导入sql数据,数字类型字段变科学计数的简单解决办法