zoukankan      html  css  js  c++  java
  • 【矩阵乘法】CDOJ1610 黑红梅方

    考虑用4^n-不存在连续4个相同的。

    f(i,j,k,l)表示以i为结尾的序列,最后三位分别是j,k,l时的方案。

    可以转移,写一个64*64的转移矩阵。

    貌似可以优化?……未完待续。

    #include<cstdio>
    #include<vector>
    #include<iostream>
    using namespace std;
    typedef long long ll;
    #define MOD 1000000009ll
    typedef vector<ll> vec;
    typedef vector<vec> mat;
    mat I;
    mat operator * (const mat &A,const mat &B){
    	mat C(A.size(),vec(B[0].size()));
    	for(int i=0;i<A.size();++i){
    		for(int k=0;k<B.size();++k){
    			for(int j=0;j<B[0].size();++j){
    				C[i][j]=(C[i][j]+A[i][k]*B[k][j]%MOD)%MOD;
    			}
    		}
    	}
    	return C;
    }
    mat Quick_Pow(mat a,ll p)
    {
        if(!p){
        	return I;
        }
        mat res=Quick_Pow(a,p>>1ll);
        res=res*res;
        if((p&1ll)==1ll){
        	res=res*a;
        }
        return res;
    }
    ll Quick_Pow(ll a,ll p)
    {
        if(!p){
        	return 1;
        }
        ll res=Quick_Pow(a,p>>1ll);
        res=res*res%MOD;
        if((p&1ll)==1ll){
        	res=(a%MOD*res)%MOD;
        }
        return res;
    }
    ll n;
    int main(){
    	cin>>n;
    	I.assign(64,vec(64));
    	for(int i=0;i<64;++i){
    		for(int j=0;j<64;++j){
    			I[i][j]=0;
    		}
    	}
    	for(int i=0;i<64;++i){
    		I[i][i]=1;
    	}
    	mat A(64,vec(1));
    	for(int i=0;i<64;++i){
    		A[i][0]=1;
    	}
    	mat b(64,vec(64));
    	for(int i=0;i<64;++i){
    		for(int j=0;j<64;++j){
    			b[i][j]=0;
    		}
    	}
    	for(int i=0;i<4;++i){
    		for(int j=0;j<4;++j){
    			for(int k=0;k<4;++k){
    				int hang=i*16+j*4+k;
    				if(i==j || j==k || i==k){
    					for(int l=0;l<4;++l){
    						int lie=l*16+i*4+j;
    						b[hang][lie]=1;
    					}
    				}
    				else{
    					for(int l=0;l<4;++l){
    						if(l==i || l==j || l==k){
    							int lie=l*16+i*4+j;
    							b[hang][lie]=1;
    						}
    					}
    				}
    			}
    		}
    	}
    //	for(int i=0;i<64;++i){
    //		for(int j=0;j<64;++j){
    //			printf("%I64d ",b[i][j]);
    //		}
    //		puts("");
    //	}
    	mat c=Quick_Pow(b,n-3ll)*A;
    	ll n4=Quick_Pow(4ll,n);
    	ll tmp=0;
    	for(int i=0;i<64;++i){
    		tmp=(tmp+c[i][0])%MOD;
    	}
    	cout<<(n4-tmp+MOD)%MOD<<endl;
    	return 0;
    }
  • 相关阅读:
    布局类组件介绍
    容器类组件介绍
    应用升级介绍
    Http组件的介绍
    Webview组件和HTML的介绍
    数据绑定介绍
    业界最具影响力MySQL精品文章荟萃(300篇)
    业界最有价值的 ASP.NET 博文汇总
    一个引号导致1个小时网站打不开
    这个世界从来没有任何一件工作叫“钱多、事少、离家近”
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6935697.html
Copyright © 2011-2022 走看看