http://192.168.102.138/JudgeOnline/problem.php?cid=1485&pid=2
知识点:1.矩阵快速幂,凡是齐次递推或类似递推都要考虑矩快优化
2.思考题目的特殊性,对特殊情况特殊对待,并从特殊情况入手,找到解决办法
解法:1.上下左右全部都有接口连上,1
2.上下左右全部没接口连上,直接快速幂
3.只有一组有接口连上:设三个值:x=黑格的个数 y=相邻两格都是黑格的个数 z:有多少个接口,然后矩快递推
#include <bits/stdc++.h> using namespace std; long long n,m,k,k1,k2,p,p1,p2,d[2][2],g[2][2],ans[2],mod=1000000007ll; char ch[1001][1001]; long long ksm(long long a,long long b){ long long s=1ll; while(b){ if(b % 2 == 1)s=(s*a)%mod; a=(a*a)%mod; b=b/2ll; } return s; } void solve(long long a){ while(a){ if(a&1ll){ ans[1ll]=(ans[0ll]*d[1ll][0ll]+ans[1ll]*d[1ll][1ll])%mod; ans[0ll]=(ans[0ll]*d[0ll][0ll])%mod; } g[0ll][0ll]=(d[0ll][0ll]*d[0ll][0ll]+d[0ll][1ll]*d[1ll][0ll])%mod; g[0ll][1ll]=(d[0ll][0ll]*d[0ll][1ll]+d[0ll][1ll]*d[1ll][1ll])%mod; g[1ll][0ll]=(d[0ll][0ll]*d[1ll][0ll]+d[1ll][0ll]*d[1ll][1ll])%mod; g[1ll][1ll]=(d[1ll][0ll]*d[0ll][1ll]+d[1ll][1ll]*d[1ll][1ll])%mod; d[0ll][0ll]=g[0ll][0ll]; d[1ll][0ll]=g[1ll][0ll]; d[0ll][1ll]=g[0ll][1ll]; d[1ll][1ll]=g[1ll][1ll]; a=a/2ll; } } int main(){ cin >> n >>m >>k; for(long long i=1ll;i<=n;i++){ scanf("%s",ch[i]+1ll); for(long long j=1ll;j<=m;j++){ if(ch[i][j]=='#')p++; if(ch[i][j]=='#'&&ch[i-1ll][j]=='#')p1++; if(ch[i][j]=='#'&&ch[i][j-1ll]=='#')p2++; } } for(long long i=1ll;i<=m;i++)if(ch[1ll][i]=='#'&&ch[n][i]=='#')k1++; for(long long i=1ll;i<=n;i++)if(ch[i][1ll]=='#'&&ch[i][m]=='#')k2++; if(k1&&k2)printf("1 "); else if(k1==0ll&&k2==0ll)printf("%lld ",ksm(p,k-1ll)); else{ if(k1){ d[0ll][0ll]=p; d[1ll][0ll]=p1; d[1ll][1ll]=k1; }else{ d[0ll][0ll]=p; d[1ll][0ll]=p2; d[1ll][1ll]=k2; } ans[0ll]=1ll; ans[1ll]=0ll; solve(k-1ll); ans[0ll]=(ans[0ll]-ans[1ll]+mod)%mod; printf("%lld ",ans[0ll]); } }