Blocks POJ - 3734

打表可得规律 an=3an-1 +bn-1 bn=4bn-1 +2^(n-1) 

dp也可,设a00 a01 a02 分别为红绿均偶 红绿一奇一偶 红绿均奇 转移矩阵快速幂

组合数学可用总方案4^n - 不符合条件的方案数 = 4^(n-1)+2^(n-1)

我找了规律。。。感觉自己low了好多。。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MOD=10007;
const int sz=4;
int n=3;
struct mat{
    int a[sz][sz];
    mat(){memset(a,0,sizeof a);}
    void initE(){for(int i=0;i<n;i++)a[i][i]=1;}
    void initfib(){a[1][0]=a[0][1]=a[0][0]=1;a[1][1]=0;}
    mat operator*(const mat&t)const{
        mat q;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            for(int k=0;k<n;k++)
                q.a[i][j]=(q.a[i][j]+a[i][k]*t.a[k][j])%MOD;
        return q;
    }
    void out(){
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++)printf("%d ",a[i][j]);printf("\n");
        }
    }
    mat operator^(int k)const{
        mat res;res.initE();
        mat m=*this;
        //res.out();m.out();
        while(k>0){
            if(k&1)res=res*m;
            m=m*m;k>>=1;
        }
        return res;
    }

};
int mp[1010];
int ans=0;
int ed;
void dfs(int now){
    if(now==ed){
        int c1,c2;
        c1=c2=0;
        for(int i=0;i<ed;i++){
            if(mp[i]==0)c1++;
            if(mp[i]==1)c2++;
        }
        if(c1%2==0&&c2%2==0)ans++;
        return ;
    }
    for(int i=0;i<4;i++){
        mp[now]=i;
        dfs(now+1);
    }
}
void init(int a[sz][sz]){
    a[0][0]=3;a[0][1]=1;
    a[1][1]=4;a[1][2]=1;
    a[2][2]=2;
}
int main(){
 
    mat m;
    m.a[0][0]=m.a[2][0]=2;
    mat q;init(q.a);
    int t;
    scanf("%d",&t);
   // m.out();q.out();
    while(t--){
        int k;
        scanf("%d",&k);
        printf("%d\n",((q^(k-1))*m).a[0][0]);
    }
    return 0;
}

 

posted @ 2017-10-09 13:51  MeowMeowMeow  阅读(151)  评论(0编辑  收藏  举报