2017沈阳网络赛 number number number

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6198

题意:   斐波拉契数列f[0]=0、f[1]=1,f[n]=f[n-1]+f[n-2](n>=2),求不能用k个斐波拉契数之和表示的最小数。

flag:找规

***规律是:f[2*k+2]-1

推荐看 RBS <<根据递推公式构造系数矩阵用于快速幂>>

时间复杂度: O(log n)

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <vector>
#define llt long long
using namespace std;

const int Mod=998244353;

void quick_Power(llt a,llt &x1,llt &y1,llt &x2,llt &y2){
    if(a==0){
        x1=1;y1=0;
        x2=0;y2=1;
        return ;
    }
    if(a==1){
        x1=1;y1=1;
        x2=1;y2=0;
        return ;
    }

    llt _x1,_x2,_y1,_y2;
    quick_Power(a/2,_x1,_y1,_x2,_y2);

        x1=(_x1*_x1%Mod+_y1*_x2%Mod)%Mod;
        y1=(_x1*_y1%Mod+_y1*_y2%Mod)%Mod;
        x2=(_x2*_x1%Mod+_y2*_x2%Mod)%Mod;
        y2=(_x2*_y1%Mod+_y2*_y2%Mod)%Mod;

    if(a%2==0) return;

    _x1=x1;_x2=x2;_y1=y1;_y2=y2;
    x1=_x1+_y1;
    y1=_x1;
    x2=_x2+_y2;
    y2=_x2;
}
int main(){

    int k;
    while(~scanf("%d",&k)){
        llt x1,x2,y1,y2;
        quick_Power(2*k+2,x1,y1,x2,y2);
        printf("%lld\n",(x1-1+Mod)%Mod);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38786088/article/details/79830885