• 【JZOJ4787】数格子【矩阵乘法】


    题目大意:

    题目链接:https://jzoj.net/senior/#main/show/4787
    求用1×21 imes 2的骨牌铺满4×n4 imes n的方格的方案数。


    思路:

    这种类型的题目很显然是公式或者规律的。况且n109nleq 10^9这种O(n)O(n)都不可以过的还能有什么做法XD
    惯例:打表找规律。

    nn 1 2 3 4 5 6 7 8 9 10
    ansans 1 5 11 36 95 281 781 2245 6336 18061

    肉眼看了5min5min还是什么都没看出来。
    这是个好网站
    往下翻,就可以看到
    a(n)=a(n1)+5a(n2)+a(n3)a(n4)a(n)=a(n-1)+5*a(n-2)+a(n-3)-a(n-4)

    所以利用这个公式就可以拿到60pts60pts的高分了。
    这个显然是可以用矩阵乘法搞的呀。
    在这里插入图片描述

    这样复杂度就是loglog级别的了。


    代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    
    const ll A[5][5]=
    {
    	{0,0,0,0,0},
    	{0,1,5,1,-1},
    	{0,1,0,0,0},
    	{0,0,1,0,0},
    	{0,0,0,1,0}
    };
    
    int n,MOD;
    ll f[5],a[5][5];
    
    void mul(ll f[5],ll a[5][5])
    {
    	ll c[5]={0,0,0,0,0};
    	for (int i=1;i<=4;i++)
    		for (int j=1;j<=4;j++)
    			c[i]=(c[i]+a[i][j]*f[j])%MOD;
    	memcpy(f,c,sizeof(c));
    }
    
    void mulself(ll a[5][5])
    {
    	ll c[5][5];
    	memset(c,0,sizeof(c));
    	for (int i=1;i<=4;i++)
    		for (int j=1;j<=4;j++)
    			for (int k=1;k<=4;k++)
    				c[i][j]=(c[i][j]+a[i][k]*a[k][j])%MOD;
    	memcpy(a,c,sizeof(c));
    }
    
    /*
    1,5,11,36,95,281,781,2245,6336,18061
    a(n)=a(n-1)+5*a(n-2)+a(n-3)-a(n-4)
    */
    
    int main()
    {
    	while (scanf("%d%d",&n,&MOD)==2 && n && MOD)
    	{
    		if (n==1) {printf("1
    "); continue;}
    		if (n==2) {printf("5
    "); continue;}
    		if (n==3) {printf("11
    "); continue;}
    		if (n==4) {printf("36
    "); continue;}
    		memcpy(a,A,sizeof(A));
    		f[1]=36,f[2]=11,f[3]=5,f[4]=1;
    		n-=4;
    		while (n)
    		{
     			if (n&1) mul(f,a);
    			mulself(a);
    			n>>=1;
    		}
    		cout<<(f[1]%MOD+MOD)%MOD<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    HDU 4325 Contest 3
    HDU 4324 Contest 3
    HDU 4323 Contest 3
    HDU 4321 Contest 3
    HDU 4320 Contest 3
    HDU 4314 Contest 2
    HDU 4313 Contest 2
    HDU 4318 Contest 2
    12-----简单认识下margin
    11-----broder(边框)
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998168.html
Copyright © 2020-2023  润新知