直接根据题意构造矩阵
[ left[
egin{array}{ccc}
A_{n-2}\\
A_{n-1}\\
A_{n-2}*A_{n-1}\\
A_{n-2}^2\\
A_{n-1}^2\\
S_{n-1}\\
end{array}
ight]
*
left[
egin{array}{ccc}
0 & 1 & 0 & 0 & 0 & 0 \\
y & x & 0 & 0 & 0 & 0 \\
0 & 0 & y & 0 & x & 0 \\
0 & 0 & 0 & 0 & 1 & 0 \\
0 & 0 & 2*x*y & y * y & x * x & 0 \\
0 & 0 & 2*x*y & y * y & x * x & 1 \\
end{array}
ight]
=
left[
egin{array}{ccc}
A_{n-1}\\
A_{n}\\
A_{n-1}*A_{n}\\
A_{n-1}^2\\
A_{n}^2\\
S_{n}\\
end{array}
ight]
]
#include<bits/stdc++.h>
using namespace std;
const int mod = 10007;
struct jz{
long long g[10][10];
void init(){
memset(g,0,sizeof(g));
}
void one(){
memset(g,0,sizeof(g));
for(int i = 1; i <= 6; ++ i) g[i][i] = 1;
}
};
jz operator * (jz a,jz b){
jz c; c.init();
for(int i = 1; i <= 6; ++ i)
for(int j = 1; j <= 6; ++ j)
for(int k = 1; k <= 6; ++ k)
c.g[i][j] += a.g[i][k] * b.g[k][j] % mod, c.g[i][j] %= mod;
return c;
}
jz ksm(jz x,long long y){
jz z; z.one();
while(y){
if(y & 1) z = z * x;
y >>= 1;
x = x * x;
}
return z;
}
jz a,b;
long long n,x,y;
int main(){
while(scanf("%lld%lld%lld",&n,&x,&y) != EOF){
a.init(); b.init(); x %= mod; y %= mod;
a.g[1][2] = 1;
a.g[2][1] = y; a.g[2][2] = x;
a.g[3][3] = y; a.g[3][5] = x;
a.g[4][5] = 1;
a.g[5][3] = 2 * x * y % mod; a.g[5][4] = y * y % mod; a.g[5][5] = x * x % mod;
a.g[6][3] = 2 * x * y % mod; a.g[6][4] = y * y % mod; a.g[6][5] = x * x % mod; a.g[6][6] = 1;
/*b.g[1][1] = 1;
b.g[2][1] = 1;
b.g[3][1] = 1;
b.g[4][1] = 1;
b.g[5][1] = 1;
b.g[6][1] = 2;*/
n -= 1;
a = ksm(a, n);
long long ans = 0;
ans += (a.g[6][3] + a.g[6][4]) % mod, ans %= mod;
//printf("%lld
",ans);
ans += (a.g[6][5] + 2 * a.g[6][6] % mod) % mod, ans %= mod;
printf("%lld
",ans);
/*for(int i = 1; i <= 6; ++ i){
printf("%lld ",a.g[6][i]);
puts("");
}
b = b * a;
printf("%lld
",b.g[6][1]);*/
}
return 0;
}
/*
An-2 010000 An-1
An-1 yx0000 An
An-2 * An-1 00y0x0 An-1*An
An-2^2 000010 An-1^2
An-1^2 002xyYX0 An^2
S(n-1) 002xyYX1 S(n)
*/