首页 > 代码库 > HDU 2842
HDU 2842
f(n)代表把n个环全部拿下来要用的次数
要将第n个拿下, 前n-2个要拿下来,所以要用f(n-2)+1,
并且第n-1个在环上,要将第n-1个拿下来,必须前n-2个环要放回去即f(n-2)
然后再拿下前n-3,然后才拿下第n-1个,即(f(n-3)+1)
然后再把前n-3个放回去,。。。一直循环得到: f(n)=f(n-2)+1+f(n-2)+f(n-3)+1+f(n-3)+......+f(n-n);
于是递推公式为:f(n)=2*f(n-2)+f(n-1)+1;
矩阵快速幂
#include <iostream>
#include <string.h>
using namespace std;
long n;
struct M{
long long t[3][3]; //用long long,不能用int和long。。。。被坑了1次.....
M(){
memset(t,0,sizeof(t));
}
void init(){
t[0][0]=t[0][2]=t[1][0]=t[2][2]=1;
t[0][1]=2;
}
void E(){
for(int i=0;i<3;i++){
t[i][i]=1;
}
}
};
M multiply(M a,M b){
M c;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
for(int k=0;k<3;k++){
c.t[i][j]=(c.t[i][j]+(a.t[i][k]%200907)*(b.t[k][j]%200907))%200907;
}
}
}
return c;
}
M powM(M a,long k){
M tem;
tem.E();
while(k){
if(k&1)tem=multiply(a,tem);
a=multiply(a,a);
k>>=1;
}
return tem;
}
int main(){
M a,b,c;
a.t[0][0]=2;
a.t[1][0]=1;
a.t[2][0]=1;
b.init();
while(cin>>n){
if(n==0)break;
if(n<3){
cout<<a.t[2-n][0]<<endl;
}
else {
c=powM(b,n-2);
c=multiply(c,a);
cout<<c.t[0][0]%200907<<endl;
}
}
return 0;
}