[2018] Xuzhou network game Morgana Net (matrix fast power)

You give a n * n matrix A, and a m * m matrix B (m% 2 == 1)

B is the convolution kernel, so you do use B to A t times the convolution operation, and for each element of A calculated value to the modulo-2, so A will eventually be a 01 matrix.

Since you ask, A in the number of elements = 1 through t

1<=t<=1e9,1<=n<=8,1<=m<=n

 

SOLUTION:

Two-dimensional matrix developed into a one-dimensional

A matrix approach is then put into a 1 * (n * n) one-dimensional vector, and constructs a (n * n) * (n * n) of the auxiliary matrix

We observed that for each of the elements A, each convolution product of the desired position value is fixed, then we advance the pretreatment

Because only the values ​​0 and 1, it can be accelerated by bitset

 

CODE:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <bitset>
using namespace std;
 
typedef long long ll;
const int MOD = 2;
const int MAXN = 40000;
 
typedef struct {
 
    bitset<80> m[80];
    int sizx,sizy;
 
}Matrix;
int n,m;
Matrix cb;
inline Matrix Mul(Matrix a, Matrix b)
{
    Matrix c;
 
    c.sizx=a.sizx;
    c.sizy=b.sizy;
    cb.sizy=b.sizx;
    cb.sizx=b.sizy;
    for(int i=0;i<b.sizy;i++)
    {
        cb.m[i].reset();
        for(int j=0;j<b.sizx;j++)
        {
            cb.m[i][j]=b.m[j][i];
        }
    }
    for (int i = 0; i < a.sizx; i++)
    {
        c.m[i].reset();
        for (int j = 0; j < b.sizy; j++)
        {
            bitset<80> tmp=(a.m[i]&cb.m[j]);
            c.m[i][j]=tmp.count()&1;
        }
    }
    return c;
}
 
inline Matrix fastm(Matrix a, ll num)
{
    Matrix res;
    for(int i=0;i<a.sizx;i++) res.m[i].reset();
    res.sizx=a.sizx;
    res.sizy=a.sizy;
    for(int i=0;i<a.sizx;i++)
        res.m[i][i]=1;
    while (num)
    {
        if (num & 1)
            res = Mul(res, a);
        num >>= 1;
        a = Mul(a, a);
    }
    return res;
}
 
 
Matrix a,b,c;
int main()
{
    int cas;
    scanf("%d",&cas);
    while(cas--)
    {
 
        int t;
        scanf("%d%d%d",&n,&m,&t);
        a.sizx=1;a.sizy=n*n;
        a.m[0].reset();
        for(int i=0;i<n*n;i++)
        {
            int tmp;
            scanf("%d",&tmp);
            a.m[0][i]=tmp&1;
        }
 
        for(int i=0;i<m;i++)
        {
            for(int j=0;j<m;j++)
            {
                int tmp;
                scanf("%d",&tmp);
                b.m[i][j]=tmp&1;
            }
        }
 
        c.sizx=c.sizy=n*n;
        int num=0;
        int in=0;
        m=m>>1;
        for(int i=0;i<n*n;i++) c.m[i].reset();
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                for(int p=i-m;p<=i+m;p++)
                {
                    for(int q=j-m;q<=j+m;q++)
                    {
                        in=p*n+q;
                        if(p>=0&&p<n&&q>=0&&q<n)
                        {
                            c.m[in][num]=(b.m[p-i+m][q-j+m]);
                        }
 
                    }
 
                }
                num++;
            }
 
        }
        c=fastm(c,t);
        a=Mul(a,c);
 
        printf("%d\n",a.m[0].count());
    }
 
 
}

  

Guess you like

Origin www.cnblogs.com/zhangbuang/p/11202620.html