0
点赞
收藏
分享

微信扫一扫

Recurrences UVA - 10870


主要就是公式推导 还是直接上图

其实这种题靠自己推出公式来还是蛮爽的。。Recurrences UVA - 10870_uva

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

int gg[20][20],mat[20][20],ans[20][20];
int f[20],a[20];
int d,n,m;

void init()
{
int sum,i,j;

memset(gg,0,sizeof(gg));
for(i=1;i<=d;i++)
{
gg[i][d]=f[d-i+1]%m;
}
for(j=d-1;j>=1;j--)
{
sum=0;
for(i=1;i<=d;i++)
{
sum=(sum+(gg[i][j+1]*a[i])%m)%m;
}
gg[1][j]=sum;
for(i=2;i<=d;i++)
{
gg[i][j]=gg[i-1][j+1];
}
}

memset(mat,0,sizeof(mat));
for(i=1;i<=d;i++)
{
mat[i][1]=a[i]%m;
}
for(i=2;i<=d;i++)
{
mat[i-1][i]=1;
}

return;
}

void add(int a[][20],int b[][20],int c[][20])
{
int t[20][20];
int i,j;
memset(t,0,sizeof(t));
for(i=1;i<=d;i++)
{
for(j=1;j<=d;j++)
{
t[i][j]=(a[i][j]%m+b[i][j]%m)%m;
}
}
memcpy(c,t,sizeof(t));
return;
}

void mul(int a[][20],int b[][20],int c[][20])
{
int t[20][20];
int i,j,k;
memset(t,0,sizeof(t));
for(i=1;i<=d;i++)
{
for(j=1;j<=d;j++)
{
t[i][j]=0;
for(k=1;k<=d;k++)
{
t[i][j]+=((a[i][k]%m)*(b[k][j])%m)%m;
t[i][j]%=m;
}
}
}
memcpy(c,t,sizeof(t));
return;
}

void quickpow()
{
int i,j;
memset(ans,0,sizeof(ans));
for(i=1;i<=d;i++)
{
ans[i][i]=1;
}
while(n>0)
{
if(n%2==1)
{
mul(ans,mat,ans);
}
mul(mat,mat,mat);
n/=2;
}
return;
}

int main()
{
int i;
while(scanf("%d%d%d",&d,&n,&m)!=EOF)
{
if(d==0&&n==0&&m==0) break;
for(i=1;i<=d;i++)
{
scanf("%d",&a[i]);
a[i]%=m;
}
for(i=1;i<=d;i++)
{
scanf("%d",&f[i]);
f[i]%=m;
}
init();
if(n<=2*d-1)
{
if(1<=n&&n<=d)
{
printf("%d\n",gg[n][d]%m);
}
else
{
n-=(d-1);
printf("%d\n",gg[1][d-n+1]%m);
}
}
else
{
n-=(2*d-1);
quickpow();
mul(gg,ans,ans);
printf("%d\n",ans[1][1]%m);
}
}
return 0;
}

 

 


举报

相关推荐

0 条评论