卧薪尝胆,厚积薄发。
NOI2013 矩阵游戏
Date: Wed Oct 24 18:52:20 CST 2018
In Category:
NoCategory
Description:
$F[1][1]=1,F[i][j]=a\times F[i][j-1]+b (j\ne1)F[i][1]=c\times F[i-1][m]+d (i\ne1)$
,求
$F[n][m]$
。
$1\leqslant n,m\leqslant 10^{1000000}$
Solution:
$$
\begin{align}
f[n][m]&=a^{m-1}\times f[n][1]+\frac{a^{m-1}-1}{a-1}\times b\\
&=a^{m-1}\times c\times f[n-1][m]+d\times a^{m-1}+\frac{a^{m-1}-1}{a-1}\times b
\end{align}
$$
设
$x=a^{m-1}\times c,y=d\times a^{m-1}+\frac{a^{m-1}-1}{a-1}\times b$
。
$$
\begin{align}
f[n][m]&=x\times f[n-1][m]+y\\
&=x^{n-1}\times f[1][m]+\frac{x^{n-1}-1}{x-1}\times y\\
&=x^{n-1}\times (a^{m-1}\times f[1][1]+\frac{a^{m-1}-1}{a-1}\times b)+\frac{x^{n-1}-1}{x-1}\times y
\end{align}
$$
注意
$a$
或
$c=1$
时的特判。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
using namespace std;
typedef long long ll;
pair<ll,ll> n,m;
int a,b,c,d;
#define MOD 1000000007
#define fi first
#define se second
inline pair<ll,ll> read()
{
register pair<ll,ll> res;
res.fi = res.se = 0;
register char c = getchar();
while(!isdigit(c))c = getchar();
while(isdigit(c))
{
res.fi = ((res.fi << 1) + (res.fi << 3) + c - '0') % MOD;
res.se = ((res.se << 1) + (res.se << 3) + c - '0') % (MOD - 1);
c = getchar();
}
return res;
}
int power(int a,int b)
{
int res = 1;
while(b > 0)
{
if(b & 1)res = 1ll * res * a % MOD;
a = 1ll * a * a % MOD;
b = b >> 1;
}
return res;
}
int main()
{
n = read();m = read();
cin >> a >> b >> c >> d;
int f11 = 1;
int f1m;
if(a == 1)f1m = (1ll * power(a,int(m.se) - 1) * f11 % MOD + 1ll * (m.fi - 1 + MOD) * b % MOD) % MOD;
else f1m = (1ll * power(a,int(m.se) - 1) * f11 % MOD + 1ll * (power(a,int(m.se) - 1) - 1 + MOD) * power(a - 1,MOD - 2) % MOD * b) % MOD;
int x = 1ll * power(a,int(m.se) - 1) * c % MOD;
int y;
if(a == 1)y = (1ll * d * power(a,int(m.se) - 1) % MOD + 1ll * (m.fi - 1 + MOD) * b % MOD) % MOD;
else y = (1ll * d * power(a,int(m.se) - 1) % MOD + 1ll * (power(a,int(m.se) - 1) - 1 + MOD) * power(a - 1,MOD - 2) % MOD * b) % MOD;
int fnm;
if(a == 1 && c == 1)fnm = (1ll * power(x,int(n.se) - 1) * f1m % MOD + 1ll * (n.fi - 1 + MOD) * y % MOD) % MOD;
else fnm = (1ll * power(x,int(n.se) - 1) * f1m % MOD + 1ll * (power(x,int(n.se) - 1) - 1 + MOD) * power(x - 1,MOD - 2) % MOD * y) % MOD;
cout << fnm << endl;
return 0;
}
In tag:
数学-费马小定理
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡