中南林业科技大学第十一届程序设计大赛--序列求和 (逆元)

走着

题目描述

定义S(n) = 12 + 22 + … + n2,输出S(n) % 1000000007。
注意:1 < n < 1e18。

输入描述:

多组输入,输入直到遇到EOF为止;

第一行输入一个正整数n。

输出描述:

输出S(n) % 1000000007的结果。

输入

1
2
1000

输出

1
5
333833500

思路

逆元 加 公式
公式:
这里写图片描述

AC

#include<bits/stdc++.h> 
#define N 100005
#define ll long long
using namespace std;
const int mod = 1000000007;
ll extgcd(ll a, ll b, ll &x, ll &y){    //扩展欧几里得;计算a%b,a关于b的逆元X,b关于a的逆元Y 
    ll d = a;
    if(b == 0){
        x = 1;
        y = 0;
    }else{
        d = extgcd(b, a % b, y, x);
        y -= a / b * x;
    }
    return d;   //返回a%b 
}
ll inv(ll a, ll mod){   //求a对mod的逆元 
    ll x, y;
    int d = extgcd(a, mod, x, y);
    if(d != 1)
        return -1;
    else
        return (x + mod) % mod;

} 
int main() {
    ll n;
    while (cin >> n) {
        ll inv_6 = inv(6, mod);
        ll t1 = n % mod;
        ll t2 = (n + 1) % mod;
        ll t3 = ((2 * (n % mod)) % mod + 1) % mod;
        //除六转化成逆元,相乘 
        ll t4 = inv_6 % mod;
        ll aa = (t1 * t2) % mod;
        ll bb = (t3 * t4) % mod;
        ll ans = (aa * bb) % mod;
        cout << ans << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henuyh/article/details/80384142