[51nod]1341 混合序列[公式推导]

题意

a_0=0,a_n=pa_{n-1}+r(n \geq 1);b_0=3,b_n=qb_{n-1}(n \geq 1)

给定p,q,r,n\sum_{i=0}^{n}(a_{i}b_{n-i})

数据范围:1 \leq p,q,r,n\leq 10^9

题解

妥妥的公式推导题(数据范围也可以看出)

\{b_n\}很容易得到通项公式b_n=3q^n(条件有q \neq 0)

主要问题就在于如何处理\{a_n\},若\{a_n\}也为a_n=qa_{n-1}那么计算是很容易的(对于递推式计算会因为有常数而使结果复杂)

那么我们构造\{c_n\},c_n=a_n+k,c_n=qc_{n-1},我们可以解出k=\frac{r}{q-1}

 

k存在则ans=\sum_{i=0}^{n}(c_i-k)b_{n-i}=3c_0\sum_{i=0}^{n}p^{i}q^{n-i}+k\sum b_i

对于\sum b_i,分q=1,q>1进行讨论即可

那么问题主要在于求解\sum p^{i}q^{n-i},有这么一个等式p^{n+1}-q^{n+1}=(p-q)(\sum_{i=0}^{n}p^{i}q^{n-i})

p \neq q\sum p^{i}q^{n-i}=\frac{p^{n+1}-q^{n+1}}{p-q}; 若p=q,\sum p^i q^{n-i}=(n+1)p^n

于是我们解决k存在的情况

 

k不存在,说明q=1

a_n=nr,ans=3r\sum_{i=0}^n iq^{n-i}=arq^n\sum \frac{i}{q^i},若q\neq 1这里有一个错位求和,q=1时计算结果显然

(q-1)S_n=\frac{q^n-1}{q^{n+1}-q^n}-\frac{n}{q^n}

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

using LL = long long;
const LL MOD = 1e9 + 7;
LL p, q, r, n, ans;
LL qpow(LL, LL);

int main(){
  cin >> p >> q >> r >> n;
  if(p == 1){
    if(q == 0)
      ans = n * r % MOD * 3 % MOD;
    else{
      if(q == 1)
        ans = 3 * r % MOD * ((n) * (n + 1) / 2 % MOD) % MOD;
      else{
        ans = 3 * r % MOD * qpow(q, n) % MOD;
        LL sum, qn, qn_;
        qn_ = qpow(q, n - 1), qn = qn_ * q % MOD;
        sum = ((qn - 1 + MOD) % MOD * qpow((qn - qn_ + MOD) % MOD, MOD - 2) % MOD - n * qpow(qn, MOD - 2) % MOD + MOD) % MOD;
        sum = sum * qpow((q - 1 + MOD) % MOD, MOD - 2) % MOD;
        ans = ans * sum % MOD;
      }
    }
  }else{
    LL k = r * qpow((p - 1 + MOD) % MOD, MOD - 2) % MOD;
    LL c0 = k;
    if(q == 1)
      ans = 3 * k % MOD * (n + 1) % MOD;
    else
      ans = 3 * k % MOD * ((qpow(q, n + 1) - 1 + MOD) % MOD) % MOD * qpow((q - 1 + MOD) % MOD, MOD - 2) % MOD;
    LL sum;
    sum = 3 * c0 % MOD;
    if(p == q)
      sum = sum * (n + 1) % MOD * qpow(p, n) % MOD;
    else{
      sum = sum * ((qpow(p, n + 1) - qpow(q, n + 1) + MOD) % MOD) % MOD * qpow((p - q + MOD) % MOD, MOD - 2) % MOD;
    }
    ans = (sum - ans + MOD) % MOD;
  }
  cout << ans << endl;
  return 0;
}

LL qpow(LL x, LL n){
  LL res = 1;
  while(n){
    if(n & 1) res = res * x % MOD;
    x = x * x % MOD;
    n >>= 1;
  }
  return res;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值