Just Oj 2017C语言程序设计竞赛高级组A: 求近似值(矩阵快速幂)

A: 求近似值

时间限制: 1 s      内存限制: 128 MB     

提交 我的状态

题目描述

求⌊(5–√+6–√)2n⌋⌊(5+6)2n⌋%9932017。

例如:n=1,(5–√+6–√)2(5+6)2=21.9544....,⌊(5–√+6–√)2⌋⌊(5+6)2⌋%9932017=21。

输入

第一行输入T,表示n的个数。(1<=T<=200000)

下面T行每行一个数,表示n。(0<=n<=10^18)

输出

按照题意输出答案。

样例输入

3
0
1
2

样例输出

1
21
481

题解:就是一个数学题目,将f(n)分解为两个互相关联的函数An和B(n);
通过矩阵求出最终的A(n)和B(n),问题就迎刃而解了;
 

#include<iostream>
#include<string.h>
#include<algorithm>
#define inf 9932017
#define ll long long
using namespace std;
struct mat{
        ll p[2][2];
        mat(){
                memset(p,0,sizeof(p));
        }
};
mat mul(mat A,mat B){
        mat C;
        for(int i=0;i<2;i++)
                for(int j=0;j<2;j++)
                        for(int k=0;k<2;k++)
                                C.p[i][j]+=A.p[i][k]*B.p[k][j]%inf;
        return C;
}
mat pow(mat A,ll n){
        mat B;
        B.p[0][0]=11;
        B.p[1][0]=2;
        while(n){
                if(n&1)
                        B=mul(A,B);
                A=mul(A,A);
                n>>=1;
        }
        return B;
}
int main()
{
        int T;
        ll n;
        scanf("%d",&T);
        mat A;
        A.p[0][0]=11;   A.p[0][1]=60;
        A.p[1][0]=2;     A.p[1][1]=11;
        while(T--)
        {
                scanf("%lld",&n);
                if(!n)
                        printf("1\n");
                else 
                        printf("%lld\n",(2*pow(A,n-1).p[0][0]-1)%inf);//2An-1
        }
        return 0;
}

 

 

posted @ 2018-12-01 12:07  aeipyuan  阅读(208)  评论(0编辑  收藏  举报