洛谷Oj-连续自然数和-前缀和 + 二分查找
来源:互联网 发布:sql developer查询 编辑:程序博客网 时间:2024/06/08 08:25
问题描述:
对一个给定的自然数M,求出所有的连续的自然数段,这些连续的自然数段中的全部数之和为M。
例子:1998+1999+2000+2001+2002 = 10000,所以从1998到2002的一个自然数段为M=10000的一个解。
AC代码:
long long num[2000010],sum[2000010];//数组sum用来做前缀和int bsearch(int l,int r,long long key)//二分查找模板{ int mid; while(l <= r) { mid = (l + r) / 2; if(sum[mid] == key) return mid; else if(sum[mid] > key) r = mid-1; else l = mid+1; } return -1;//如果没找到就返回-1}int main(){ int m; cin >> m;//输入 for(int i = 1; i <= m; ++i) { num[i] = i; sum[i] = sum[i - 1] + num[i];//预处理前缀和 }// for(int i = 1; i <= m - 1; ++i)//初始代码,时间复杂度O(n^2),TLE// for(int j = i; j <= m - 1; ++j)// if(sum[j] - sum[i - 1] == m)//看到这个等式,马上想到可以优化// printf("%d %d\n",i,j); int ans;//记录二分查找函数的返回值,避免重复调用 for(int i = 1; i <= m - 1; ++i) { ans = bsearch(i,m,m + sum[i - 1]);//这里前缀和是严格递增的,故可以使用二分查找,优化后时间复杂度为O(nlogn) if(ans != -1)//找到了 printf("%d %d\n",i,ans); } return 0;}
解决方法:
连续自然数 =》 区间段 =》 前缀和
sum[j] - sum[i - 1] == m =》变形为sum[j] == sum[i - 1] + m=》如果能在sum数组中找到sum[j],则满足题意
阅读全文
0 0
- 洛谷Oj-连续自然数和-前缀和 + 二分查找
- 洛谷1147 连续自然数和
- 洛谷1147 连续自然数和
- 洛谷P1147 连续自然数和
- 连续自然数和-洛谷 1147
- 洛谷P1147 连续自然数和
- 洛谷 P1147 连续自然数和
- 洛谷 P1147 连续自然数和
- 洛谷 P1147 连续自然数和
- 洛谷 p1147 连续自然数和
- 高斯求和等差数列前缀和(洛谷1147 连续自然数和)
- 连续自然数和(easy)
- 连续自然数和
- 1312 连续自然数和
- P1147 连续自然数和
- P1147 连续自然数和
- P1147 连续自然数和
- P1147 连续自然数和
- [bzoj4934]kangroo
- CMake快速入门教程:实战
- macOS为PhantomJS设置path
- 项目中曾经遇到过的问题整理
- C++ 私有继承
- 洛谷Oj-连续自然数和-前缀和 + 二分查找
- VJ框架 与 人脸检测/物体检测 详解
- 初始化问题
- linux下安装keepalived (nginx高可用)
- 如何打发空闲时间,来吧,做个项目
- PVAnet配置
- [LeetCode]553. Optimal Division
- 分享一些精彩的博客、问答等等
- Tomcat8.5 不能进入Manager App