Fraction of Fractal

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]);
    }
}
原文地址:https://www.cnblogs.com/xyj1/p/13820141.html