水平太渣. 唯有看完解题报告+标程 AK这套题.

 

  需要取上整,核心点加上了一个小于1的小数.

当n = 2时,有 , 然后可以验证下当n取其他值时也满足。所以就有

, 则其特征方程的两个解为:

当 n = 2. 时, 其特征方程为:

化简得到:

因为

所以有:

S_2 - 2*a*S_1 + (a^2+b) = 0

得到线性递推关系, 然后矩阵快速幂随便搞搞就好了。

// Sn = ceil( [a + sqrt(b)]^n ) % m;

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

typedef long long LL;

struct Matrix{
    LL mat[2][2];
    void zero(){memset(mat,0,sizeof(mat));}
    void unit(){zero();mat[0][0]=mat[1][1]=1;}
}A,T;

Matrix mult( Matrix a, Matrix b, int mod ){
    Matrix c; c.zero();
    for(int i = 0; i < 2; i++)
    for(int k = 0; k < 2; k++)
    for(int j = 0; j < 2; j++)
    {
        c.mat[i][j] += a.mat[i][k]*b.mat[k][j];
        c.mat[i][j] %= mod;
    }
    return c;
}
Matrix Pow( Matrix x, int n, int mod ){
    Matrix c; c.unit();
    while(n){
        if(n&1) c = mult(c,x,mod);
        x = mult(x,x,mod);
        n >>= 1;
    }
    return c;
}

void init(int a,int b){
    int a1 = 2*a, b1 = b-a*a;
    T.mat[0][0] = 0; T.mat[0][1] = 1;
    T.mat[1][0] = b1; T.mat[1][1] = a1;
    A.zero();
    A.mat[0][0] = 2; A.mat[1][0] = 2*a;
}
int main(){
    int a,b,n,m;
    while( scanf("%d%d%d%d",&a,&b,&n,&m) != EOF){
        init(a,b);
        T = Pow( T, n, m );
        A = mult( T, A, m );
        printf("%lld\n", (A.mat[0][0]+m)%m );
    }
    return 0;
}
View Code

相关文章:

  • 2021-04-15
  • 2021-08-04
  • 2021-10-17
  • 2022-12-23
  • 2021-10-14
  • 2022-02-01
  • 2022-12-23
  • 2021-06-27
猜你喜欢
  • 2021-11-18
  • 2022-12-23
  • 2021-07-13
  • 2022-12-23
  • 2021-11-02
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案