如题,菜菜,大佬们救救
//我服了这题。。。手推矩阵
//nodgd我承认你确实恶心到我了
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 15;
LL n,M;
LL p,q,r,t;
LL u,v,w;
LL x,y,z;
struct matrix //矩阵
{
LL a[N][N];
LL h,l; //height, length高度和长度
matrix(LL _h, LL _l){
memset(a,0,sizeof(a));
h = _h, l = _l;
}
//p.s. []不可重载为友元函数
LL* operator [](int x) { //让外部可以直接以形如z[i][j]的方式调用矩阵,而不是z.a[i][j]
return a[x];
}
friend matrix operator * (matrix a, matrix b);
friend matrix operator *= (matrix &a, matrix b){
a = a*b;
}
friend matrix quickpow(matrix a, LL x);
friend void print(matrix a);
};
LL slowMul(LL a,LL b); //龟速乘,防止爆long long
matrix base(11,11); //11*11的运算矩阵
matrix ans(1,11);
//矩阵内分别为{a(k-1), b(k-1), c(k-1), a(k), b(k), c(k), (k-1)^2, k-1, w^(k-1), z^(k-1), 1}
// {a(k-1), b(k-1), c(k-1), a(k), b(k), c(k), (k-1)^2, k-1, w^(k-1), z^(k-1), 1}
// => {a(k), b(k), c(k), a(k+1), b(k+1), c(k+1), k^2, k, w^k, z^k, 1}
//已知:
//a(k+2)=p*a(k+1)+q*a(k)+b(k+1)+c(k+1)+r*(k^2)+t*k+1, 则
//a(k+1) = p*a(k) + q*a(k-1) + b(k) + c(k) + r*((k-1)^2) + t*(k-1) + 1
//同理可知
//b(k+1) = u*b(k) + v*b(k-1) + a(k) + c(k) + w^(k-1)
//c(k+1) = x*c(k) + y*c(k-1) + a(k) + b(k) + z^(k-1) + k-1 + 2
LL ans1, ans2, ans3;
void __init__();
int main(){
scanf("%lld%lld",&n,&M);
scanf("%lld%lld%lld%lld",&p,&q,&r,&t);
scanf("%lld%lld%lld",&u,&v,&w);
scanf("%lld%lld%lld",&x,&y,&z);
__init__();
if(n == 1){
ans1 = ans2 = ans3 = 1;
}
else if(n == 2){
ans1 = ans2 = ans3 = 3;
}
else{
ans = ans*quickpow(base, n-2);
ans1 = ans[0][3];
ans2 = ans[0][4];
ans3 = ans[0][5];
}
printf("nodgd %lld\n", ans1);
printf("Ciocio %lld\n", ans2);
printf("Nicole %lld\n", ans3);
return 0;
}
void __init__(){ //初始化
//矩阵内分别为{a(k-1), b(k-1), c(k-1), a(k), b(k), c(k), (k-1)^2, k-1, w^(k-1), z^(k-1), 1}
//芝士矩阵
LL o[N][N] = {
{0, 0, 0, q, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, v, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, y, 0, 0, 0, 0, 0},
{1, 0, 0, p, 1, 1, 0, 0, 0, 0, 0},
{0, 1, 0, 1, u, 1, 0, 0, 0, 0, 0},
{0, 0, 1, 1, 1, x, 0, 0, 0, 0, 0},
{0, 0, 0, r, 0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, t, 0, 1, 2, 1, 0, 0, 0},
{0, 0, 0, 0, 1, 0, 0, 0, w, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, z, 0},
{0, 0, 0, 1, 0, 2, 1, 1, 0, 0, 1},
};
for(int i = 0;i < 11;i++){
for(int j = 0;j < 11;j++) base[i][j] = o[i][j];
}
ans[0][0] = ans[0][1] = ans[0][2] = 1;
ans[0][3] = ans[0][4] = ans[0][5] = 3;
ans[0][6] = ans[0][7] = 1;
ans[0][8] = w; ans[0][9] = z; ans[0][10] = 1;
}
LL slowMul(LL a, LL b){
if(a > b) swap(a,b);
LL res = 0;
LL temp = a;
while(b){
if(b&1){
res = (res+temp)%M;
}
b >>= 1;
temp = (temp+temp)%M;
}
return res;
}
//重载*运算符,作矩阵乘法
matrix operator * (matrix a, matrix b){
//C = A*B => Cij = Aik * Bkj
matrix res(a.h, b.l);
if(a.l != b.h) return res; //第一个矩阵的长度必须等于第二个矩阵的宽度
//设第一个矩阵A长la高ha, 第二个矩阵B长lb高hb, 返回一个ha*lb的矩阵
for(int i = 0;i < a.h;i++){
for(int j = 0;j < b.l;j++){
for(int k = 0;k < a.l;k++){
//A矩阵每一行中的k个元素乘上B矩阵每一列中的K个元素
res[i][j] += slowMul(a[i][k], b[k][j])%M;
res[i][j] %= M;
}
}
}
return res;
}
matrix quickpow(matrix a, LL x){
if(!x || a.l != a.h) return a;
matrix temp = a; //a^1
//将res初始化为全1,便于乘算
matrix res(a.h, a.l);
for(int i = 0;i < a.h;i++){
res[i][i] = 1;
}
while(x){
if(x&1){
res = res * temp;
}
x >>= 1;
temp *= temp; //a^2, a^4, a^8...
}
return res;
}
void print(matrix a){
for(int i = 0;i < a.h;i++){
for(int j = 0;j < a.l;j++){
printf("%d ",a[i][j]);
}
puts("");
}
return;
}