BZOJ1002:[FJOI2007]轮状病毒
矩阵树定理大佬题。
要看详细证明看这个:http://vfleaking.blog.163.com/blog/static/17480763420119685112649/
最后化成f[n]=3*f[n-1]-f[n-2]+2的式子
就变成高精度模板题了。emmm
#include <cstdio>
#include <cstring>
using namespace std;
int n;
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct Bignum {
int num[1000];
void clear() {
memset(num,0,sizeof(num));
}
Bignum operator *(const int &a) const {
Bignum c;c.clear();
for(int i=1;i<=num[0];i++) {
c.num[i]+=num[i]*a;
c.num[i+1]+=c.num[i]/10;
c.num[i]%=10;
}c.num[0]=num[0];
if(c.num[c.num[0]+1])c.num[0]++;
return c;
}
Bignum operator -(const Bignum &a) const {
Bignum c;c=*this;
for(int i=1;i<=c.num[0];i++) {
if(c.num[i]<a.num[i])
c.num[i+1]--,c.num[i]+=10;
c.num[i]-=a.num[i];
}
while(!c.num[c.num[0]])c.num[0]--;
return c;
}
Bignum operator +(const int &a) const {
Bignum c;c=*this;
for(int i=1;i<=c.num[0];i++) {
if(i==1)c.num[i]+=a;
c.num[i+1]+=c.num[i]/10;
c.num[i]%=10;
}c.num[0]=num[0];
return c;
}
void print() {
for(int i=num[0];i;i--)
printf("%d",num[i]);
}
}f[101];
int main() {
n=read();
f[1].num[0]=f[1].num[1]=1;
f[2].num[0]=1,f[2].num[1]=5;
for(int i=3;i<=n;i++)
f[i]=f[i-1]*3-f[i-2]+2;
f[n].print();
return 0;
}