• 【poj3734】矩阵乘法


    题解:

    若当前有i个格子。
    2个是偶数的方案数为a[i]
    1个是偶数的方案数为b[i]
    0个是偶数的方案数为c[i]

    a[i+1]=2*a[i](i+1染成黄或蓝)+b[i](把奇数变为偶数)
    b[i+1]=2*a[i](把某个偶数变为奇数)+2*b[i](i+1染成黄或蓝)+2*c[i](把某个奇数变为偶数)
    c[i+1]=b[i](把偶数变为奇数)+2*c[i](i+1染成黄或蓝)

    解析式难想,要学会这种分类递推的方法。

    然后就可以推出

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    using namespace std;
    
    const int N=1000000010,Mod=10007;
    
    struct node{
        int sx,sy;
        int s[4][4];
    };
    
    node mult(node a,node b)
    {
        node c;
        c.sx=a.sx;c.sy=b.sy;
        memset(c.s,0,sizeof(c.s));
        for(int i=1;i<=a.sx;i++)
            for(int j=1;j<=b.sy;j++)
                for(int k=1;k<=a.sx;k++)
                {
                    c.s[i][j]+=(a.s[i][k]*b.s[k][j])%Mod;
                    c.s[i][j]%=Mod;
                }
        return c;
    }
    
    void solve(int x)
    {
        node a;
        a.sx=a.sy=3;
        a.s[1][1]=2;a.s[1][2]=1;a.s[1][3]=0;
        a.s[2][1]=a.s[2][2]=a.s[2][3]=2;
        a.s[3][1]=0;a.s[3][2]=1;a.s[3][3]=2;
        node b;
        b.sx=b.sy=3;
        memset(b.s,0,sizeof(b.s));
        for(int i=1;i<=3;i++) b.s[i][i]=1;
        while(x)
        {
            if(x&1) b=mult(b,a);
            a=mult(a,a);
            x>>=1;
        }
        node c;
        c.sx=3;c.sy=1;
        c.s[1][1]=1;
        c.s[2][1]=c.s[3][1]=0;
        c=mult(b,c);
        
        printf("%d
    ",c.s[1][1]);
        return ;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            int x;
            scanf("%d",&x);
            solve(x);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    HDU 1251 统计难题(字典树模板题)
    POJ 1182 食物链(带权并查集)
    FJUT 2351 T^T的图论(并查集)
    10.QT程序框架与connect
    9.正则表达式
    8.QList QMap QVariant
    7.treeview
    6.图形化列表查询显示
    5.listview(QStringList QStringListModel)
    4.QList
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/4820856.html
Copyright © 2020-2023  润新知