ACM-ICPC 2018 徐州赛区网络预赛 Morgana Net

题意:Morgana Net

题解:把a矩阵每一位根据公式推出递推矩阵,然后用矩阵快速幂,比赛没想到啊,,

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=2;
struct mat
{
    int n, m;
    ll a[70][70];
    mat() {}
    void init(int _n, int _m)
    {
        n = _n;
        m = _m;
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++) a[i][j] = 0;
        }
    }
    mat operator + (const mat &B)const
    {
        mat C;
        C.init(n,m);
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                C.a[i][j]=(a[i][j]+B.a[i][j])%mod;
        return C;
    }
    mat operator*(const mat &P)const
    {
        mat ret;
        ret.init(n,m);
        for(int i = 0; i < n; i++)
        {
            for(int k = 0; k < m; k++)
            {
                if(a[i][k])
                {
                    for(int j = 0; j < P.m; j++)
                    {
                        ret.a[i][j] = (a[i][k] * P.a[k][j] + ret.a[i][j])%mod ;
                    }
                }
            }
        }
        return ret;
    }
    mat operator^(const ll &P)const
    {
        ll num = P;
        mat ret, tmp = *this;
        ret.init(n,m);
        for(int i = 0; i < n; i++) ret.a[i][i] = 1;
        while(num)
        {
            if(num & 1) ret = ret * tmp;
            tmp = tmp * tmp;
            num >>= 1;
        }
        return ret;
    }
    void view()
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                printf("%lld ",a[i][j]);
            }printf("
");
        }
    }
}ap,ad;
int a[10][10],b[50][50],n,m,t;
int get(int x,int y)
{
    return x*n+y;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d %d",&n,&m,&t);
        ap.init(1,n*n);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                scanf("%d",&a[i][j]);
                ap.a[0][get(i,j)]=a[i][j];
            }
        }
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&b[i][j]);
                b[i][j]%=2;
            }
        }
        ad.init(n*n,n*n);
        int mm=(m-1)/2;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                for(int p=i-mm;p<=i+mm;p++)
                {
                    for(int q=j-mm;q<=j+mm;q++)
                    {
                        //cout<<"SSS"<<p-i+mm+1<<" "<<q-j+mm+1<<endl;
                        if(p>=0&&p<n&&q>=0&&q<n&&b[p-i+mm][q-j+mm])
                        {
                            ad.a[get(p,q)][get(i,j)]=1;
                        }
                    }
                }
            }
        }
      //  ad.view();
        ap=ap*(ad^(t));
        int ans=0;
        for(int i=0;i<n*n;i++)
        {
            ans+=ap.a[0][i];
        }
        printf("%d
",ans);
    }
}
原文地址:https://www.cnblogs.com/lhclqslove/p/9715925.html