hdu6050 Funny Function【打表+找规律+矩阵快速幂】

来源:互联网 发布:sql unique 编辑:程序博客网 时间:2024/06/13 01:13

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6050
题意:看公式,求fm,1
解析:打表找规律
直接找答案的规律,根据题目的公式来推,太难了,直接打个表看规律,好看点
先处理处第一行(用矩阵快速幂来做),然后分奇偶来找规律,找规律是玄学问题,难以解释。。。(详情见代码)
打表

#include <bits/stdc++.h>using namespace std;typedef long long LL;LL dp[10][100];int n,m;LL dfs(int a,int b){    if(dp[a][b]!=0)        return dp[a][b];    if(a==1)    {        if(b>2)            dp[a][b]=dfs(1,b-1)+2*dfs(1,b-2);        else            return 1;    }    else    {        for(int i=0;i<n;i++)            dp[a][b]+=dfs(a-1,b+i);    }    return dp[a][b];}int main(void){    memset(dp,0,sizeof(dp));    dp[1][1]=dp[1][2]=1;    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++)        printf("%d: %d\n",i,dfs(i,1));    for(int i=1;i<=m;i++)        printf("%d  ",dfs(1,i));    puts("");    return 0;}
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int mod = 1e9+7;struct martix{    ll a[10][10];    int n,m;    martix() {}    martix(int _n,int _m)    {        n = _n;        m = _m;        memset(a,0,sizeof(a));    }    martix operator * (const martix &b)const    {        martix res(n,b.m);        for(int i=0;i<n;i++)        {            for(int j=0;j<b.m;j++)            {                for(int k=0;k<m;k++)                    res.a[i][j] = (res.a[i][j]+a[i][k]*b.a[k][j]+mod)%mod;            }        }        return res;    }    void print()    {        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)                printf("%I64d ",a[i][j]);            puts("");        }    }};martix qpow(martix x,ll n){    martix res(x.n,x.m);    for(int i=0;i<res.n;i++)        res.a[i][i] = 1;    while(n>0)    {        if(n&1)            res = res*x;        x = x*x;        n>>=1;    }    return res;}ll qpow(ll x,ll n){    ll res = 1;    while(n>0)    {        if(n&1)            res = res*x%mod;        x = x*x%mod;        n>>=1;    }    return res;}int main(void){    int t;    scanf("%d",&t);    while(t--)    {        ll n,m;        scanf("%I64d %I64d",&n,&m);        martix op(2,2);        martix ss(2,1);        op.a[0][0] = 0,op.a[0][1] = 1;        op.a[1][0] = 2,op.a[1][1] = 1;        ss.a[0][0] = 1,ss.a[1][0] = 1;        if(n==1 || m==1)            puts("1");        else        {            martix ans = qpow(op,n);            ans = ans*ss;            ll res = ans.a[0][0];            ll tt = qpow(2,n)-1;            if(n%2)            {                ans = qpow(op,n-1);                ans = ans*ss;                ll tmp = ans.a[0][0]-1;                martix t1(2,2);                martix t2(2,1);                t1.a[0][0] = tt,t1.a[0][1] = 1;                t1.a[1][0] = 0,t1.a[1][1] = 1;                t2.a[0][0] = res;t2.a[1][0] = -tmp;                ans = qpow(t1,m-2);                ans = ans*t2;                printf("%I64d\n",(ans.a[0][0]+mod)%mod);            }            else                printf("%I64d\n",((res-1)*qpow(tt,m-2))%mod);        }    }    return 0;}
原创粉丝点击