题解[LuoguP1707 刷题比赛]
题目描述
给定\(n,P,p,q,r,t,u,v,w,x,y,z\) ,三个递推式:
\[a_{k+2}=pa_{k+1}+qa_{k}+b_{k+1}+c_{k+1}+rk^2+tk+1
\]
\[b_{k+2}=ub_{k+1}+vb_{k}+a_{k+1}+c_{k+1}+w^k
\]
\[c_{k+2}=xc_{k+1}+yc_{k}+a_{k+1}+b_{k+1}+z^k+k+2
\]
求\(a_n , b_n ,c_n(\%P)\)
Sol
一定先静下心来,把题目看好了。
变量名什么的尽量跟题目一样,耐心推矩阵。
最好还是和题目一样设式子,因为观察发现题目给的式子最简单,没有什么\((k+1)^2,(k-1)^2\)之类要拆的式子。
递推\(11\)个量:
\[a_{k+1},b_{k+1},c_{k+1},a_k,b_k,c_k,k,k^2,w^k,z^k,1
\]
小技巧:凡是随着\(k\)的变化而变化的值都应放入初始矩阵中,转移矩阵只放常量。每一个矩乘都可以往这上面靠。
推出\(11×11\)的矩阵就直接套模板,可以啦(≧▽≦)/
初始矩阵:
3 0 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0
k 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0
w 0 0 0 0 0 0 0 0 0 0
z 0 0 0 0 0 0 0 0 0 0
k^2 0 0 0 0 0 0 0 0 0 0
转移矩阵:
p 1 1 q 0 0 t 1 0 0 r
1 u 1 0 v 0 0 0 1 0 0
1 1 x 0 0 y 1 2 0 1 0
1 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 0 0 0
0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 w 0 0
0 0 0 0 0 0 0 0 0 z 0
0 0 0 0 0 0 2 1 0 0 1
别忘了龟速乘。
Code
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct xbk{
ll m[12][12];
}a,st,flag,f0;
ll n,P,p,q,r,t,u,v,w,x,y,z;
inline ll read(){
ll w=0;
char ch=getchar();
while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9'){
w=(w<<3)+(w<<1)+(ch^48);
ch=getchar();
}
return w;
}
inline ll mul1(ll a,ll b){
ll res=0;
while(b){
if(b&1) res=(res+a)%P;
a=(a+a)%P;
b>>=1;
}
return res;
}
xbk mul(xbk aa,xbk bb){
xbk c=f0;
for(int i=1;i<=11;i++){
for(int j=1;j<=11;j++){
for(int k=1;k<=11;k++){
c.m[i][j]=(c.m[i][j]+mul1(bb.m[i][k],aa.m[k][j])%P)%P;
}
}
}
return c;
}
xbk ksm(xbk aa,ll b){
xbk res=flag;
while(b){
if(b&1) res=mul(res,aa);
aa=mul(aa,aa);
b>>=1;
}
return res;
}
int main(){
n=read(),P=read();
p=read(),q=read(),r=read(),t=read();
u=read(),v=read(),w=read();
x=read(),y=read(),z=read();
for(int i=1;i<=11;i++){
for(int j=1;j<=11;j++){
flag.m[j][j]=1,a.m[i][j]=0,f0.m[i][j]=0;
}
}
a.m[1][1]=p,a.m[1][2]=1,a.m[1][3]=1,a.m[1][4]=q,a.m[1][7]=t,a.m[1][8]=1,a.m[1][11]=r;
a.m[2][1]=1,a.m[2][2]=u,a.m[2][3]=1,a.m[2][5]=v,a.m[2][9]=1;
a.m[3][1]=1,a.m[3][2]=1,a.m[3][3]=x,a.m[3][6]=y,a.m[3][7]=1,a.m[3][8]=2,a.m[3][10]=1;
a.m[4][1]=1,a.m[5][2]=1,a.m[6][3]=1;
a.m[7][7]=1,a.m[7][8]=1;
a.m[8][8]=1;
a.m[9][9]=w;
a.m[10][10]=z;
a.m[11][7]=2,a.m[11][8]=1,a.m[11][11]=1;
st.m[1][1]=3,st.m[2][1]=3,st.m[3][1]=3;
st.m[4][1]=1,st.m[5][1]=1,st.m[6][1]=1;
st.m[7][1]=1,st.m[8][1]=1,st.m[9][1]=w;
st.m[10][1]=z,st.m[11][1]=1;
xbk ans=ksm(a,n-2);
ans=mul(st,ans);
printf("nodgd %lld\nCiocio %lld\nNicole %lld\n",ans.m[1][1],ans.m[2][1],ans.m[3][1]);
return 0;
}