您的位置:首页 > 其它

【2016-沈阳赛区现场赛-C】

2016-11-01 09:44 267 查看
跟斐波那契数列很像的递推,要加上i^4,用到二项式定理,使用矩阵快速幂,矩阵为7阶。

递推矩阵为

ll qiqi[10][10]=

{

    {0,0,0,0,0,0,0,0},

    {0,1,2,1,4,6,4,1},

    {0,1,0,0,0,0,0,0},

    {0,0,0,1,4,6,4,1},

    {0,0,0,0,1,3,3,1},

    {0,0,0,0,0,1,2,1},

    {0,0,0,0,0,0,1,1},

    {0,0,0,0,0,0,0,1}

};

从1开始。

基础矩阵为

{b}

{a}

{16}

{8}

{4}

{2}

{1}

快速幂一下然后乘起来就是答案。

就是你需要f(n+1),所以你要提供f(n),f(n-1),n^4

你需要f(n+1),f(n),(n+1)^4,所以你需要提供n^3,n^2,n^1,1。

然后就全了,比较一下新旧状态就很容易得到转移矩阵,无非就是需要哪些项,然后给个系数就OK。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll mod=2147493647ll;

ll qiqi[10][10]=
{
{0,0,0,0,0,0,0,0},
{0,1,2,1,4,6,4,1},
{0,1,0,0,0,0,0,0},
{0,0,0,1,4,6,4,1},
{0,0,0,0,1,3,3,1},
{0,0,0,0,0,1,2,1},
{0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,1}
};

struct jz
{
ll MAP[10][10];
ll m,n;
void init1(ll a,ll b)
{
m=7;
n=1;
MAP[1][1]=b;
MAP[2][1]=a;
MAP[3][1]=16;
MAP[4][1]=8;
MAP[5][1]=4;
MAP[6][1]=2;
MAP[7][1]=1;
}
void init2()
{
m=n=7;
for(ll i=1;i<=7;i++)
for(ll j=1;j<=7;j++)
MAP[i][j]=qiqi[i][j];
}
jz operator * (const jz& rhs) const
{
jz ret;
ret.m=m;
ret.n=rhs.n;
for(ll i=1;i<=ret.m;i++)
for(ll j=1;j<=ret.n;j++)
{
ret.MAP[i][j]=0;
for(ll k=1;k<=n;k++)
ret.MAP[i][j]=(ret.MAP[i][j]+(MAP[i][k]*rhs.MAP[k][j])%mod)%mod;
}
return ret;
}
jz operator ^ (ll n) const
{
jz ret;
jz x=*this;
ret.m=ret.n=m;
memset(ret.MAP,0,sizeof(ret.MAP));
for(ll i=1;i<=m;i++) ret.MAP[i][i]=1;
while(n)
{
if(n&1) ret=ret*x;
x=x*x;
n>>=1;
}
return ret;
}
void prll()
{
for(ll i=1;i<=m;i++)
{
for(ll j=1;j<=n;j++)
printf("%I64d ",MAP[i][j]);
puts("");
}
}
};

int main()
{
ll T;
scanf("%I64d",&T);
while(T--)
{
ll N,a,b;
scanf("%I64d %I64d %I64d",&N,&a,&b);
if(N==1) printf("%I64d\n",a);
else if(N==2) printf("%I64d\n",b);
else
{
jz hehe;
hehe.init2();
jz haha;
haha.init1(a,b);
hehe=hehe^(N-2);
//hehe.prll();
haha=hehe*haha;
printf("%I64d\n",haha.MAP[1][1]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: