Simple Matrix
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 471 Accepted Submission(s): 158
Use the geometric progression as the first row of the simple matrix: c0,n=bn
Use the arithmetic progression as the first column of the simple matrix: cn,0=an
Calculate the item at n -th row,
Given the two sequences, Huazheng wants to know the value of cn,m , but he is too busy with his research to figure it out. Please help him to work it out. By the way, you can assume that c0,0=0 .
For each test case, there is only one line containing six non-negative integers b1,q,a1,d,n,m . ( 0≤n≤10000 ). All integers are less than 231 .
2
3 10 1 1 3 3
5 2 1 10 4 2
Case #1: 423
Case #2: 140
题目大意:
就是给了一个矩阵,这个矩阵的第
0
行是等比数列(首项
公差
d
已知),剩余的满足一个式子
解题思路:
这个题显然要分开求,意思就是先求等比数列的,再求等差数列的,等差数列可以通过找找规律就可以发现是一个类似杨辉三角的东西,重点是
解决等比数列的问题。因为
m
太大了,所以我们要想办法快速的计算第
办法构造一个等比数列,首先观察第
1
行和第
表示的是第
i
行 第
数列
(F(1,j)+x) = q∗(F(1,j−1)+x)
解得
x = b1q−1
,以此类推可以得到
n
个等比数列,那么我们现在多加了一项就在
的这个数列中减去,那么现在我们就是要求 ∑ni=1ai∗C(n+m−1−i,n−i)+b1∗qm+n−1(q−1)n
My Code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef long long LL;
const LL MOD = 1e9+7;
const int MAXN = 1e6+5;
void Exgcd(LL a, LL b, LL &x, LL &y){
if(b == 0){
x = 1;
y = 0;
return;
}
LL x1, y1;
Exgcd(b, a%b, x1, y1);
x = y1;
y = x1 - (a/b)*y1;
}
LL pow_mod(LL a, LL b){
LL ans = 1;
while(b){
if(b & 1)
ans = (ans*a) % MOD;
b>>=1LL;
a = (a*a) % MOD;
}
return ans;
}
LL suma[MAXN];///等差数列的第一项
int main()
{
///freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
for(int cas=1; cas<=T; cas++){
LL b1, q, a1, d, n, m;
scanf("%lld%lld%lld%lld%lld%lld",&b1,&q,&a1,&d,&n,&m);
if(n==0 && m==0){
printf("Case #%d: %0\n",cas);
continue;
}
b1 %= MOD, q %= MOD;
a1 %= MOD, d %= MOD;
LL now = b1, x, y, tmp;
for(LL i=1; i<=n; i++){
Exgcd(q-1, MOD, x, y);
x = (x % MOD + MOD) % MOD;
x = now*x%MOD;///now / (q-1)
now = (now + x) % MOD;
suma[i] = (a1 + (i-1)*d%MOD - x);
suma[i] = (suma[i] % MOD + MOD) % MOD;
}
/**等比数列的 start**/
Exgcd(q-1, MOD, x, y);
LL Inv = (x % MOD + MOD) % MOD;
LL ans = pow_mod(Inv, n);
x = pow_mod(q, m+n-1);
ans = (ans * x % MOD) * b1 % MOD;
/**等比数列的 end**/
ans = (ans + suma[n]) % MOD;///特判一下
tmp = 1;
for(LL i=n-1; i>0; i--){
Exgcd(n-i, MOD, x, y);
x = (x % MOD + MOD) % MOD;
x = (x *((n+m-1)-i))%MOD;
tmp = tmp * x % MOD;
ans = (ans + tmp*suma[i]%MOD) % MOD;
}
printf("Case #%d: %lld\n",cas,ans);
}
return 0;
}