G. 小青争的零食
解题思路:举证快速幂。假设零食为0,蔬菜为1。按照题意:00->01,01->11,01->10,10->01,10->00,11->10,11->11。对于n,前两个好确定只有00,01,10,11,后面的填充便可以由上面的确定。
a n s = [ a ∗ a a ∗ b b ∗ a b ∗ b ] ∗ [ 0 b 0 0 0 0 a b a b 0 0 0 0 a b ] ans = \begin{bmatrix}a*a&a*b&b*a&b*b\end{bmatrix} * \begin{bmatrix}0&b&0&0\\0&0&a&b\\a&b&0&0\\0&0&a&b\end{bmatrix} ans=[a∗aa∗bb∗ab∗b]∗⎣⎢⎢⎡00a0b0b00a0a0b0b⎦⎥⎥⎤
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double lf;
typedef unsigned long long ull;
typedef pair<int,int>P;
const int inf = 0x7f7f7f7f;
const ll INF = 1e16;
const int N = 1e5+10;
const ll mod = 1e9+7;
const double PI = acos(-1.0);
const double eps = 1e-4;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
inline string readstring(){string str;char s=getchar();while(s==' '||s=='\n'||s=='\r'){s=getchar();}while(s!=' '&&s!='\n'&&s!='\r'){str+=s;s=getchar();}return str;}
int random(int n){return (int)(rand()*rand())%n;}
void writestring(string s){int n = s.size();for(int i = 0;i < n;i++){printf("%c",s[i]);}}
typedef struct node{
ll mx[5][5];
}mx;
mx multiply(mx a,mx b){
mx c;
for(int i = 1;i <= 4;i++){
for(int j = 1;j <= 4;j++){
c.mx[i][j] = 0;
for(int k = 1;k <= 4;k++){
c.mx[i][j] = (c.mx[i][j]+(a.mx[i][k]*b.mx[k][j])%mod)%mod;
}
}
}
return c;
}
mx fast_power(mx a,ll p){
mx ans;
for(int i = 1;i <= 4;i++){
for(int j = 1;j <= 4;j++) ans.mx[i][j] = 0;
ans.mx[i][i] = 1;
}
while(p){
if(p&1) ans = multiply(a,ans);
p >>= 1;
a = multiply(a,a);
}
return ans;
}
void solve(ll n,ll a,ll b){
if(n == 1ll){
cout<<a+b<<endl;
return;
}
mx c;
for(int i = 1;i <= 4;i++){
for(int j = 1;j <= 4;j++){
c.mx[i][j] = 0;
}
}
c.mx[1][2]=c.mx[2][4]=c.mx[3][2]=c.mx[4][4]=b;
c.mx[2][3]=c.mx[3][1]=c.mx[4][3]=a;
c = fast_power(c,n-2ll);
ll sum = 0;
for(int j = 1;j <= 4;j++){
for(int i = 1;i <= 4;i++){
ll x;
if(i == 1) x = (a*a)%mod;
else if(i == 2) x = (a*b)%mod;
else if(i == 3) x = (a*b)%mod;
else x = (b*b)%mod;
x = (x*c.mx[i][j])%mod;
sum = (sum+x)%mod;
}
}
cout<<sum<<endl;
}
int main(){
srand((unsigned)time(NULL));
ll n,a,b;
while(~scanf("%lld%lld%lld",&n,&a,&b)){
solve(n,a,b);
}
return 0;
}