Queuing HDU2604

时间:2023-03-08 21:58:03

一道递推题目

得到递推关系为  f[n]=f[n-1]+f[n-3]+f[n-4];

用普通的枚举算法会超时

所以要用矩阵快速幂来加速

转化为矩阵即为:

+
1 0 1 1       F(N-1)  F(N)       
1 0 0 0  *    F(N-2)  =   F(N-1)   
0 1 0 0       F(N-3)  F(N-2)
0 0 1 0       F(N-4)  F(N-3)

1 0 1 1(n-4)       F(4)  F(N)       
1 0 0 0            *      F(3)  =   F(N-1)   
0 1 0 0                   F(2)  F(N-2)
0 0 1 0                   F(1)  F(N-3)

所以f(n) 为 矩阵的n-4次幂  的第一行 与已知的相乘    (n-4 为  n-3-1即可   这是差值 再加一为个数)

#include<iostream>
#include<cstdio>
#include<cstring> using namespace std; int n,k; int q[]={,,,,};
struct matrix{
int arr[][];
}; matrix multi( matrix a,matrix b )
{
matrix c;
for(int i=;i<;i++)
for(int j=;j<;j++){
c.arr[i][j]=;
for(int w=;w<;w++)
c.arr[i][j]=(c.arr[i][j]+a.arr[i][w]*b.arr[w][j]%k)%k;
}
return c;
} int fast(matrix a,int x){
matrix ans;
memset(ans.arr,,sizeof(ans.arr));
for(int i=;i<;i++)ans.arr[i][i]=; while(x){
if(x&){
ans=multi(ans,a);
}
x>>=;
a=multi(a,a);
}
int sum=;
for(int i=;i<;i++)
{
sum+=ans.arr[][i]*q[-i];
sum%=k;
}
return sum;
} int main(){ while(scanf("%d%d",&n,&k)==)
{
if(n<=){printf("%d\n",q[n]%k);continue;}
else
{
matrix a={,,,,,,,,,,,,,,,};
printf("%d\n",fast(a,n-)%k);
}
}
return ;
}

矩阵还是用结构体写方便。