[2018]徐州ネットワークゲームモルガナネット(マトリックス高速電力)

あなたは、n * nの行列Aを与え、M * Mの行列B(M%2 == 1)

Aは、最終的に01行列になるようあなたは、T回畳み込み演算へ、及びモジュロ2の演算値の各要素にBを使用しないので、Bは、畳み込みカーネルです。

あなたはトンを通じて要素の数= 1で、Aを確認して下さい

1 <= T <= 1e9,1 <= N <= 8,1 <= M <= N

 

溶液:

一次元に展開2次元マトリクス

マトリックスアプローチは次いで補助マトリックス(N * N)* 1 *(N×n個)一次元ベクトルに入れ、及び(N×n個)を構成されています

我々は、我々は、前処理を進め、元素Aのそれぞれに対して、所望の位置の値の各畳み込み積が一定であることが観察され

のみ値0と1なぜなら、それはビット集合によって加速することができます

 

コード:

#include <cstdioを> 
する#include <アルゴリズム> 
の#include <CStringの> 
する#include <ビットセット> 
使用して名前空間std。
 
typedefの長い長いLL。
const int型MOD = 2; 
const int型MAXN = 40000; 
 
構造体のtypedef { 
 
    ビット集合<80> M [80]。
    int型sizx、sizy。
 
}マトリックス; 
N INT、M。
行列CB。
インラインマトリックスムル(マトリックス、行列B)
{ 
    行列C。
 
    c.sizx = a.sizx。
    c.sizy = b.sizy。
    cb.sizy = b.sizx。
    cb.sizx = b.sizy。
    以下のために(; iは<b.sizy I ++は、I = 0 INT)
    { 
        cb.mを[I] .RESET()。
        (J ++ INT J = 0; J <b.sizx)のために
        {
            cb.m [I] [J] = BM [J] [I]; 
        } 
    } 
    のために(iは++; iは<a.sizx I = 0 INT)
    { 
        [I] .RESET()センチ。
        用(int型J = 0; J <b.sizy; J ++)
        { 
            ビット集合<80> TMP =(AM [I]&cb.m [J])。
            CM [I] [J] = tmp.count() - 1; 
        } 
    } 
    戻りC。
} 
 
インラインマトリックスfastm(LLのNUMを行列)
{ 
    マトリックスRES。
    res.m [I] .RESET()のために(; I <a.sizx I ++は、I = 0をINT)。
    res.sizx = a.sizx。
    res.sizy = a.sizy。
    (; iがa.sizx <I ++はiが0 = INT)のため
        res.m [i]は[I] = 1。
    一方、(NUM)
    { 
        IF(NUM&1) 
            RES =ムル(RES、A)。
        NUM >> = 1;
        =ムル(A)。
    } 
    RESを返します。
} 
 
 
、B、Cのマトリックス。
INTのmain()
{ 
    int型CAS。
    scanf関数( "%dの"、およびCAS)。
    (cas--)一方
    { 
 
        int型のT。
        scanf関数( "%D%D%D"、&N、&M&T)。
        a.sizx = 1; a.sizy = N * N。
        [0] .RESET()しています。
        以下のために(; iがn <N *; i = 0はint型私は++)
        { 
            int型TMP。
            scanf関数( "%のD"、&TMP)。
            午前[0] [I] = tmpに&1; 
        } 
 
        (i = 0 int型私は++;私がm <)のために
        { 
            (INT J = 0; J <M。
                scanf関数( "%のD"、&TMP)。
                [I] [J] = tmpのBM&1。
            } 
        } 
 
        c.sizx = c.sizy = N * N。
        int型NUM = 0; 
        = 0のint; 
        M = M >> 1。
        CM [I] .RESET()は(iは++; N * iがn <I = 0 INT)。
        以下のために(INT i = 0; iがN <、iは++)
        { 
            ための(int型J = 0であり、j <nであり、j ++)
            { 
                (INT P = IM; p <= I + M; p ++)のために
                { 
                    ため(INT Q = JM; Q <= J + M; Q ++)
                    { 
                        = P×n個+ Qにおいて、
                        (pは> = 0 && P <N && qは> = 0 && Q <N)の場合
                        {
                            CM [NUM] =(BM [P-iがM +] [Q-J + M])[IN]。
                        }
 
                    } 
 
                } 
                NUM ++。
            } 
 
        } 
        C = fastm(C、T)。
        =ムル(C); 
 
        printf( "%d個の\ n"、[0] .count(AM))。
    } 
 
 
}

  

おすすめ

転載: www.cnblogs.com/zhangbuang/p/11202620.html