Icebound and Sequence(等比数列求和、快速幂、二分思想)

题目链接:Icebound and Sequence

  • 题意:求一个等比数列的和并对其进行取模。
  • 解析:假设求等比数列首项为a, 公比为q的等比数列之和用sum(a, q)表示,可以利用二分思想得到以下规律:
    1. 当q = 1, sum(a, q) = a;
    2. 当q % 2 = 0, sum(a, q) = sum(a, x / 2) + sum(a, x / 2) * a^(x/2);
    3. 当q % 2 != 0(q != 1), sum(a, q) = sum(a, x / 2) + sum(a, x / 2) * a^(x/2) + a^x。

ps: 模运算在此不再赘述...

  • 代码:
#include<iostream>
using namespace std;
typedef long long ll;
ll p;
ll qpow(ll a, ll x)
{
    ll res = 1;
    while(x)
    {
        if(x & 1) res = res * a % p;
        x >>= 1;
        a = a * a % p;
    }
    return res;
}

ll sum(ll a, ll x)
{
    if(x == 1) return a % p;
    else if(x & 1) return ( sum(a, x / 2) % p + ( (sum(a, x / 2) % p) * (qpow(a, x / 2) % p) ) + qpow(a, x) % p ) % p;
    else return ( sum(a, x / 2) % p + ( (sum(a, x / 2) % p) * (qpow(a, x / 2) % p) ) ) % p;
}

int main()
{
    int t;
    cin >> t;
    while(t --)
    {
        ll q, n;
        cin >> q >> n >> p;
        cout << sum(q, n) << endl;
    }
    return 0;
}

posted @ 2021-04-25 21:29  ~K2MnO4  阅读(263)  评论(0)    收藏  举报