HDOJ 4602 - Partition 打表找公式,然后矩阵乘法解决..


     这种题一看就想跪...数学思维不行..推不出什么东西..索性先把打表出来看看.. 


   规律有了...实际上要求的是这么一串数列(1,2,5,12,28,64,144,320,704,1536....)的某一项...而这个数列满足F[ i ] = F[ i-1 ] *2 + 2^(i-2) ...

   构造矩阵:   M =     2   0   答案为 [ 5,2 ] * M^(n-k-2) 的[0][0]...

                                2   2  


Program:

#include<iostream>
#include<stack>
#include<queue>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<cmath>
#define ll long long
#define oo 1000000007
#define MAXN 100010
using namespace std;
struct Matrix
{
      ll a[2][2];
};
Matrix MatrixMul(Matrix a,Matrix b)
{
      int i,j,k;
      Matrix h;
      memset(h.a,0,sizeof(h.a));
      for (k=0;k<2;k++)
         for (i=0;i<2;i++)
            for (j=0;j<2;j++)
               h.a[i][j]=(h.a[i][j]+(a.a[i][k]*b.a[k][j])%oo)%oo;
      return h;         
}
Matrix GetMarix(Matrix a,int n)
{
      Matrix h,p;
      int i;
      h.a[0][0]=h.a[1][1]=1,h.a[0][1]=h.a[1][0]=0;
      p=a;
      for (i=0;i<=30;i++)
      {
            if (n & (1<<i)) h=MatrixMul(h,p);
            p=MatrixMul(p,p);
      }
      return h;
}
int main()
{   
      int Case,n,k;
      ll ans;
      Matrix h; 
      scanf("%d",&Case);
      while (Case--)
      {  
             scanf("%d%d",&n,&k);
             if (k>n)   { printf("0\n");  goto A; }
             if (k==n)  { printf("1\n");  goto A; }
             if (k==n-1){ printf("2\n");  goto A; } 
             h.a[0][0]=2,h.a[0][1]=0,h.a[1][0]=2,h.a[1][1]=2;
             h=GetMarix(h,n-k-2);
             ans=((5*h.a[0][0])%oo+h.a[1][0])%oo;
             printf("%I64d\n",ans);
             A: ;
      }
      return 0;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值