• [luogu5077][Tweetuzki 爱等差数列]


    题目链接

    思路

    数学题
    首先列出等差数列求和的式子。

    [S = frac{(n + m)(n - m + 1)}{2}(n为末项,m为首项) ]

    [S * 2= (n + m)(n - m + 1) ]

    若想让m更小,那么肯定要让等差数列中数字的数目更多。也就是让((n - m + 1))更大,而((n - m + 1))肯定是(S * 2)的因子。所以枚举一下((n - m + 1))
    假设((n - m + 1) = x)(n = x + m - 1)。然后前面那一项就变成了(x + m - 1 + m)也就是(2 * m - 1 + x)
    然后前一项也可以通过(frac{S * 2}{x})得到。这样就可以得到$$2 * m - 1 + x = frac{S * 2}{x}$$$$m = frac{S * 2 - x + 1}{2}$$,只要保证,m是正整数就行了。
    复杂度就是枚举S * 2的因子x的复杂度。因为后面的都可以用最后这个式子进行O(1)计算。

    代码

    /*
    * @Author: wxyww
    * @Date:   2018-12-10 08:36:41
    * @Last Modified time: 2018-12-10 08:40:48
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<bitset>
    using namespace std;
    typedef long long ll;
    
    ll read() {
       ll x=0,f=1;char c=getchar();
       while(c<'0'||c>'9') {
          if(c=='-') f=-1;
          c=getchar();
       }
       while(c>='0'&&c<='9') {
          x=x*10+c-'0';
          c=getchar();
       }
       return x*f;
    }
    
    int main() {
       ll s = read() * 2;
       for(ll x = sqrt(s);x >= 1;--x) {
          if(s % x) continue;
          ll m = (s / x + 1 - x);
          if(m & 1) continue;
          cout<<m / 2 <<" "<< m / 2 - 1 + x;
          return 0;
       }
       return 0;
    }
    

    一言

    萤火之光看起来比平常要更耀眼是错觉吗?今宵会成为永夜的吧。

  • 相关阅读:
    hashCode花式卖萌
    2017年的小总结
    多线程环境下的单例模式
    Servlet过滤器简单探索
    最长回文子序列(LPS)
    最短编辑距离问题
    赫夫曼编码
    DNA序列对齐问题
    同时寻找序列的最大最小值
    最长公共子序列(LCS)
  • 原文地址:https://www.cnblogs.com/wxyww/p/10094696.html
Copyright © 2020-2023  润新知