2019E1_G 等比数列求和

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44024733/article/details/102757427

等比数列求和

题目

已知 a i = a 1 × q i 1 a_{i}=a_{1}×q^{i-1} ,求 s u m i = 1 n a i sum_{i=1}^{n}a_{i}
结果可能很大,请对987654323取模

输入

第一行一个正整数t,表示数据组数

接下来t行,每行三个整数 n , a 1 , q n,a_{1},q

( 0 < n , a 1 , q < 1 0 9 , 0 < t < 10000 ) (0<n,a_{1},q<10^{9},0<t<10000)

输出

t 行,每行输出一个整数,表示等比数列的和 mod 987654323 的值。

输入样例

2
3 2 7
3 2 1

输出样例

114
6

思路

这里只给分治做法。

设等比数列和为 S S

当n为偶数的时候 S n = S n / 2 + a n / 2 + 1 × S n / 2 S_{n}=S_{n/2}+a_{n/2+1}×S_{n/2}

当n为奇数的时候 S n = S n / 2 + a n / 2 + 1 × S n / 2 + a n S_{n}=S_{n/2}+a_{n/2+1}×S_{n/2}+a_{n}

结合快速幂,总体复杂度为 l o g n logn

代码

  • 分治
#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;
typedef long long ll;
const int mod = 987654323;

ll qpow(ll a, ll n)
{
    ll x = a, res = 1;
    while (n > 0)
    {
        if (n & 1) res = (res*x) % mod;
        x = (x*x) % mod;
        n >>= 1;
    }
    return res % mod;
}
ll f(ll q, ll n)
{
    if (n == 1) return 1;
    ll tmp = f(q, n / 2);
    tmp = (tmp + tmp * qpow(q, n / 2)) % mod;
    if (n & 1)
    {
        return (tmp + qpow(q, n - 1)) % mod;
    }
    return tmp;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll a, n, q;
    int t;
    cin >> t;
    while (t--)
    {
        cin >> n >> a >> q;
        cout << (a*f(q, n)) % mod << "\n";
    }
    return 0;
}
#include <iostream>
using namespace std;

const int MOD=987654323;
unsigned long long sum(unsigned long long n,unsigned long long k)
{
    n%=MOD;
    unsigned long long ans=0;
    unsigned long long power=n;
    unsigned long long powersum=n;//S(y)
    unsigned long long mul=1;//a^x
    while (k)
    {
        if (k&1)
        {
            ans+=mul*powersum;
            ans%=MOD;
            mul*=power;
            mul%=MOD;
        }
        powersum*=(power+1);
        powersum%=MOD;
        power*=power;
        power%=MOD;

        k>>=1;
    }
    return ans;
}
int main()
{
    int T;
    cin>>T;
    while(T--){
        unsigned long long n,k,a;
        cin>>k>>a>>n;
        cout<<(((sum(n,k-1)+1%MOD)%MOD)*(a%MOD))%MOD<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44024733/article/details/102757427
今日推荐