zoukankan      html  css  js  c++  java
  • 洛谷P1147 连续自然数和【二分】

    题目https://www.luogu.org/problemnew/show/P1147

    题意:

    给定一个数m,问有多少个数对$(i,j)$,使得$i$到$j$区间的所有整数之和为m。输出所有的解。

    思路:

    根据公式$(a,b)$中的所有数之和为$frac{(a+b)(b-a+1)}{2}$,他等于定值$m$

    经过整理我们可以发现$b^2 +b - a^2 + a = 2m$,如果我们确定了$a$,这条式子对于$b$就是递增的。

    显然我们可以枚举$a$二分$b$。由于中间过程可能会爆int,所以直接就上longlong吧。

    【二分】虐狗宝典学习笔记:

    正确写出二分的流程是:(整数域)

    1、通过分析具体问题,确定左右半段哪一个是可行区间,以及mid归属哪一半段。

    2、根据分析结果,选择"$r = mid, l = mid + 1, mid = (l + r)>>1$" 和 “$l = mid, r = mid - 1, mid = (l + r + 1) >> 1$”两个配套形式之一。

    3、二分终止条件是$l==r$,该值就是答案所在位置。

    采用“$l = mid + 1, r = mid - 1$”或”$l = mid, r = mid$“来避免产生两种形势,但也相应地造成了丢失在$mid$上的答案、二分结束时可行区间未缩小到确切答案等问题,需要额外加以处理。

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<map>
     4 #include<set>
     5 #include<iostream>
     6 #include<cstring>
     7 #include<algorithm>
     8 #include<vector>
     9 #include<cmath> 
    10 #include<queue>
    11 
    12 #define inf 0x7f7f7f7f
    13 using namespace std;
    14 typedef long long LL;
    15 typedef pair<int, int> pr;
    16 
    17 LL m;
    18 
    19 int main()
    20 {
    21     scanf("%lld", &m);
    22     for(LL a = 1; a <= m; a++){
    23         LL st = a + 1, ed = m;
    24         if(a + st > m)break;
    25         while(st < ed){
    26             LL mid = (st + ed + 1) / 2;
    27             if(mid * mid - a * a + a + mid > 2 * m){
    28                 ed = mid - 1;
    29             }
    30             else {
    31                 st = mid;
    32             }
    33         }
    34         if(st * st - a * a + a + st == 2 * m)printf("%lld %lld
    ", a, st);
    35     }
    36     
    37     
    38     return 0;
    39 }
  • 相关阅读:
    Beta/Gamma事后分析
    Gamma阶段发布说明
    Gamma阶段测试报告
    展示时测试Markdown渲染
    Gamma阶段项目展示
    [技术博客] 主题适配指南
    【Gamma】Scrum Meeting 10
    [技术博客]升级 API 面临的问题
    [技术博客] JS正则活学活用
    【Gamma】Scrum Meeting 9
  • 原文地址:https://www.cnblogs.com/wyboooo/p/10374291.html
Copyright © 2011-2022 走看看