定义矩阵变换 \(F(P)=Q\),其中 \(P\) 和 \(Q\) 是\(n×n\) 的矩阵且满足 \(Q_{i,j}=(\sum^{n}_{k=1}P_{k,j}+\sum_{k=1}^nP_{i,k})mod\space p\)。给定 \(T,n,p\) 和 \(n×n\) 的初始矩阵 \(A\),求 \(A\) 经过 \(T\) 次变换后的结果矩阵。
第一行三个整数\(T,n,p\) 。
后面 \(n\) 行,每行 \(n\) 个数,代表初始矩阵 。
\(n\)行,每行 \(n\) 个数,代表结果矩阵。
3 2 10 1 2 3 4 5 6 7 8 9
4 3 2 1 0 9 8 7 6
\(n≤100,T≤10^9,2≤p≤10^9+7,P_{i,j}<p\)
我们设第\(i\)行的和为\(A[i]\),我们可以得到经过一次变换之后第\(i\)行的和\(A[i]'\)可以表示为:
\[A[i]'=sum+n*A[i] \]\(sum\)为整个矩阵的和,
\[sum'=sum*2n \]所以最终一次变换之前的A为
\[A_{finally}[i]=((A[i]*n+sum)*n+sum*2n)*n+(sum*2n)*2n... \]化简为
\(A_{finally-1}[i]=n^{T-1}*A[i]+sum*(2^{T-1}-1)*n^{T-2}\)
\((2^{T-1}-1)\)这个地方本来应该是\(\sum_{i=0}^{T-2}2^i\)
证明:
设\(S=2^{0}+2^{1}+2^{2}+...\)
\(2S=2^1+2^2+...\)
\(S=2S-S=2^n-1\)(注:底数不是2的就是\(\frac{x^n-1}{x-1}\))
然后我们可以处理出\(T-1\)次操作后的\(sum,A,B\),直接计算第\(T\)次矩阵即可
#include<bits/stdc++.h> #define ll long long using namespace std; const ll N=1e3+2; ll n,T,p,sum,val,A[N],B[N]; inline ll read(){ register ll x=0, t=1; register char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') t=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*t; } ll power(ll a,ll b){ ll res=1; while(b){ if(b&1) res=res*a%p; a=a*a%p; b>>=1; } return res; } int main(){ n=read(),T=read(),p=read(); for(ll i=1; i<=n; i++){ for(ll j=1,x; j<=n; j++){ x=read(); A[i]=(A[i]+x)%p; B[j]=(B[j]+x)%p; sum=(sum+x)%p; } } ll val=(sum*(power(2,T-1)-1+p)%p*power(n,T-2)%p)%p,t=power(n,T-1); for(ll i=1; i<=n; i++){ A[i]=(val+t*A[i]%p)%p; B[i]=(val+t*B[i]%p)%p; } for(ll i=1; i<=n; i++){ for(ll j=1; j<=n; j++){ printf("%lld ",(A[i]+B[j])%p); } printf("\n"); } return 0; }
完结撒花❀
★,°:.☆( ̄▽ ̄)/$:.°★ 。