【RQNOJ85】三個袋子【矩陣乘法】
阿新 • • 發佈:2018-11-10
題目大意:
題目連結:http://www.rqnoj.cn/problem/85
求
個球裝進
個袋子裡的總方案數。
思路:
出題人十分良心的給出了表:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
---|---|---|---|---|---|---|---|---|---|---|
方案數 | 1 | 2 | 5 | 14 | 41 | 122 | 365 | 1094 | 3281 | 9842 |
然後就變成了一道找規律的題目。
40分做法:
容易發現 。暴力遞推即可。
20到100分做法:
可以發現公式 。直接用快速冪,多少分要看你打的好不好。。。
100分做法:
矩陣乘法加速遞推。
可以發現矩陣:
然後遞推即可。
程式碼:
#include <cstdio>
#include <cstring>
using namespace std;
int n,MOD,f[3];
int a[3][3]=
{
{0,0,0},
{0,3,0},
{0,1,1}
};
void mul(int f[3],int a[3][3])
{
int c[3];
memset(c,0,sizeof(c));
for (int i=1;i<=2;i++)
for (int j=1;j<=2;j++)
c[i]=((c[i]+f[j]*a[j][i])%MOD+MOD)%MOD;
memcpy(f,c,sizeof(c));
}
void mulself(int a[3][3])
{
int c[3][3];
memset(c,0,sizeof(c));
for (int i=1;i<=2;i++)
for (int j=1;j<=2;j++)
for (int k=1;k<=2;k++)
c[i][j]=((c[i][j]+a[i][k]*a[k][j])%MOD+MOD)%MOD;
memcpy(a,c,sizeof(c));
}
int main()
{
scanf("%d%d",&n,&MOD);
f[1]=1;
f[2]=-1;
n--;
while (n)
{
if (n&1) mul(f,a);
n>>=1;
mulself(a);
}
printf("%d",f[1]%MOD);
return 0;
}