HDU 4602 Partition (矩阵乘法)

Partition

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 797    Accepted Submission(s): 322


Problem Description
Define f(n) as the number of ways to perform n in format of the sum of some positive integers. For instance, when n=4, we have
  4=1+1+1+1
  4=1+1+2
  4=1+2+1
  4=2+1+1
  4=1+3
  4=2+2
  4=3+1
  4=4
totally 8 ways. Actually, we will have f(n)=2(n-1) after observations.
Given a pair of integers n and k, your task is to figure out how many times that the integer k occurs in such 2(n-1) ways. In the example above, number 1 occurs for 12 times, while number 4 only occurs once.
 

 

Input
The first line contains a single integer T(1≤T≤10000), indicating the number of test cases.
Each test case contains two integers n and k(1≤n,k≤109).
 

 

Output
Output the required answer modulo 109+7 for each test case, one per line.
 

 

Sample Input
2 4 2 5 5
 

 

Sample Output
5 1
 

 

Source
 

 

Recommend
liuyiding
 

思路:

列出了 n=5 时 5,4,3,2,1 出现的次数为 1 2 5 12 28
f[n+1]=3*f[n]-f[n-1]-f[n-2]-..f[1]
f[n]=3*f[n-1]-f[n-2]-..f[1]
==> f[n+1]=4*f[n]-4*f[n-1]


#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

const int mod=1000000007;

struct Matrix{
    long long arr[2][2];
};

Matrix init,unit;
int n,k;
long long num[2][2]={{4,-4},{1,0}};

void Init(){
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++){
            init.arr[i][j]=num[i][j];
            unit.arr[i][j]=(i==j)?1:0;
        }
}

Matrix Mul(Matrix a,Matrix b){
    Matrix c;
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++){
            c.arr[i][j]=0;
            for(int k=0;k<2;k++)
                c.arr[i][j]=(c.arr[i][j]%mod+a.arr[i][k]*b.arr[k][j]%mod+mod)%mod;
            c.arr[i][j]%=mod;
        }
    return c;
}

Matrix Pow(Matrix a,Matrix b,int k){
    while(k){
        if(k&1){
            b=Mul(a,b);
        }
        a=Mul(a,a);
        k>>=1;
    }
    return b;
}

int main(){

    //freopen("input.txt","r",stdin);

    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&k);
        Init();
        if(k>n){
            printf("0\n");
            continue;
        }
        int tmp=n-k+1;
        if(tmp==1){
            printf("1\n");
            continue;
        }
        if(tmp==2){
            printf("2\n");
            continue;
        }
        if(tmp==3){
            printf("5\n");
            continue;
        }
        Matrix res=Pow(init,unit,tmp-3);
        //long long ans=((res.arr[0][0]%mod*5)%mod+(res.arr[0][1]%mod*2)%mod)%mod;
        long long ans=(res.arr[0][0]*5+res.arr[0][1]*2)%mod;
        cout<<ans<<endl;
    }
    return 0;
}

 



posted @ 2013-07-24 15:54  Jack Ge  阅读(786)  评论(0编辑  收藏  举报