题解 P1707 【刷题比赛】
原题地址P1707刷题比赛
由题意显然,此题为一道矩阵乘法题,已知两个矩阵求得一个未知矩阵的过程,根据题意我们可得需要来维护11个项来进行计算,则状态转移矩阵为一个\(11 * 11\)的的矩阵,初始矩阵为
\(a_{k+1}\) | \(a_k\) | \(b_{k+1}\) | \(b_k\) | \(c_{k+1}\) | \(c_k\) | \(k^2\) | \(k\) | \(w^k\) | \(z^k\) | \(1\) |
---|---|---|---|---|---|---|---|---|---|---|
所经过转以后得到的矩阵为 | ||||||||||
\(a_{k+2}\) | \(a_{k+1}\) | \(b_{k+2}\) | \(b_{k+1}\) | \(c_{k+2}\) | \(c_{k+1}\) | \((k+1)^2\) | \(k+1\) | \(w^{k+1}\) | \(z^{k+1}\) | \(1\) |
-----------: | -----------: | -----------: | -----------: | -----------: | -----------: | -----------: | -----------: | -----------: | -----------: | -----------: |
通过矩阵乘法可得转移矩阵为 | ||||||||||
![]() |
然后考虑去求即可,数据很大所以考虑用慢速乘即可
应当注意的细节
1,矩阵乘法不满足交换律,所以在相乘时应当有所注意
2,重载运算符建议封装,这样可以在多个矩阵相乘时减少不必要的代码量
3,注意\(k\)变为\(k+1\),\(k^2\)变为\((k+1)^2\)时候的细节,比较容易出错
\(Code\):
#include<bits/stdc++.h>
#define LL long long
/*呐,这份感情,什么时候能传达到呢*/
using namespace std;
template <typename T> void read(T & t){
t = 0;int f = 1;char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')f =- 1;ch = getchar();}
do{t = t * 10 + ch - '0';ch = getchar();}while(ch >= '0' && ch <= '9');t *= f;
}
LL n , m;
LL p , q , r , t;
LL u , v , w , x , y , z;
inline LL mul(LL x , LL y){
LL res = 0;
for(; y ; y >>= 1 , x = (x + x) % m){
if(y & 1){
res = (res + x) % m;
}
}
return res;
}
struct node{
LL yuni[12][12];
friend node operator * (const node &a , const node &b){
node c;
for(int i = 1;i <= 11;i ++){
for(int j = 1;j <= 11;j ++){
c.yuni[i][j] = 0;
for(int k = 1;k <= 11;k ++){
c.yuni[i][j] = (c.yuni[i][j] + mul(a.yuni[i][k] , b.yuni[k][j])) % m;
}
}
}
return c;
}
}ans , abi;
inline void quick_pow(LL b){
for(; b ; b >>= 1 , abi = abi * abi){
if(b & 1){
ans = abi * ans;
}
}
}
/*inline void quick_pow(LL b){
while(b > 0){
if(b & 1){
ans = abi * ans;
}
abi = abi * abi;
b >>= 1;
}
}*/
inline void build(){
abi.yuni[1][1] = p , abi.yuni[1][2] = q , abi.yuni[1][3] = 1 , abi.yuni[1][5] = 1 , abi.yuni[1][7] = r , abi.yuni[1][8] = t , abi.yuni[1][11] = 1;
abi.yuni[2][1] = 1;
abi.yuni[3][1] = 1 , abi.yuni[3][3] = u , abi.yuni[3][4] = v , abi.yuni[3][5] = 1 , abi.yuni[3][9] = 1;
abi.yuni[4][3] = 1;
abi.yuni[5][1] = 1 , abi.yuni[5][3] = 1 , abi.yuni[5][5] = x , abi.yuni[5][6] = y , abi.yuni[5][8] = 1 , abi.yuni[5][10] = 1 , abi.yuni[5][11] = 2;
abi.yuni[6][5] = 1;
abi.yuni[7][7] = 1 , abi.yuni[7][8] = 2 , abi.yuni[7][11] = 1;
abi.yuni[8][8] = 1 , abi.yuni[8][11] = 1;
abi.yuni[9][9] = w;
abi.yuni[10][10] = z;
abi.yuni[11][11] = 1;
}
int main(){
read(n);read(m);
read(p);read(q);read(r);read(t);
read(u);read(v);read(w);
read(x);read(y);read(z);
build();
ans.yuni[1][1] = ans.yuni[3][1] = ans.yuni[5][1] = 3;
ans.yuni[2][1] = ans.yuni[4][1] = ans.yuni[6][1] = ans.yuni[8][1] = ans.yuni[11][1] = 1;
ans.yuni[7][1] = 1 , ans.yuni[9][1] = w % m , ans.yuni[10][1] = z % m;
quick_pow(n - 2);
printf("nodgd %lld\n" , ans.yuni[1][1]);
printf("Ciocio %lld\n" , ans.yuni[3][1]);
printf("Nicole %lld\n" , ans.yuni[5][1]);
return 0;
}
有错误欢迎指出
呐,这份感情,什么时候可以传达呢