• P1147 连续自然数和


    题目传送门

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2000010;
    typedef long long LL;
    LL s[N];
    
    int main() {
        LL n;
        cin >> n;
        //预处理前缀和
        for (int i = 1; i <= n; i++) s[i] = s[i - 1] + i;
    
        //  如果我们预处理出来了s数组,那么两个变量[x,y],通过枚举y --> i 从 1~ n/2
        //  ∵s[x] - s[y-1] = n
        //  ∴s[x] = s[y-1] + n
        int m = n >> 1;                //最少两个数字的和,所以顶天是n/2
        for (int i = 1; i <= m; i++) { //枚举起点
            LL sx = s[i - 1] + n;
    
            // STL二分找到sx的位置
            int pos = lower_bound(s + 1, s + n + 1, sx) - s; // s数长度 n+1
    
            //手写二分找到x的位置
            /*
            int l = 0, r = n + 1;
            while (l < r) {
                int mid = (l + r) >> 1;
                if (sx <= s[mid])
                    r = mid;
                else
                    l = mid + 1;
            }
            int pos = l;
            */
    
            //(1)、二分找到的位置是不小于sx的值,未必就是等于,需要再次检查
            //(2)、区间长度就起码是2,如果pos==i表示 10000表示10000就不可以
            if (s[pos] - s[i - 1] == n && pos != i)
                cout << i << " " << pos << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    android Textview动态设置大小
    小米1plus MIUI RadioButton的问题
    快读
    高精集合
    清北学堂part2
    清北学堂part1
    OTZ%%%子谦。大佬
    筛质数大优化
    回文日期
    高精度加法
  • 原文地址:https://www.cnblogs.com/littlehb/p/16192311.html
Copyright © 2020-2023  润新知