BZOJ 4002--有意义的字符串(矩阵乘法)

4002: [JLOI2015]有意义的字符串

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 963  Solved: 416
[Submit][Status][Discuss]

Description

 B 君有两个好朋友,他们叫宁宁和冉冉。有一天,冉冉遇到了一个有趣的题目:输入 b;d;n,求

 

Input

一行三个整数 b;d;n

Output

 一行一个数表示模 7528443412579576937 之后的结果。

 

Sample Input

1 5 9

Sample Output

76

HINT

其中 0<b^2< = d<(b+1)2< = 10^18,n< = 10^18,并且 b mod 2=1,d mod 4=1

题目链接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=4002 

Solution

    题解PoPoQQQ 。。。膜拜orz。。。。

    思路太神了!!特征方程什么的蒟蒻表示完全不会!!

    注意:取模的时候注意要用快速乘。。。。

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define LL long long
#define ULL unsigned long long
#define mod 7528443412579576937
using namespace std;
ULL qui(ULL a,ULL b){
    ULL s=0;
    while(b){
        if(b&1)
            s=(s+a)%mod;
        b>>=1;
        a=(a+a)%mod;
    }
    return s;
}
struct jz{
    ULL x[2][2];
    friend jz operator *(const jz &a,const jz &b){
        jz tmp;
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++){
                tmp.x[i][j]=0;
                for(int k=0;k<2;k++)
                    tmp.x[i][j]=(tmp.x[i][j]+qui(a.x[i][k],b.x[k][j]))%mod;
            }
        return tmp;
    }
}A,T;
void pow(ULL z){
    while(z){
        if(z&1)
            T=T*A;
        z>>=1;
        A=A*A;
    }
}
int main(){
    ULL b,d,n,b2,f=0;
    cin>>b>>d>>n;
    if(n==0){
        printf("1\n");
        return 0;
    }
    b2=qui(b,b);
    A.x[0][0]=b;A.x[0][1]=1;A.x[1][0]=((d-b2)/4)%mod;A.x[1][1]=0;
    T.x[0][0]=b;T.x[0][1]=2;T.x[1][0]=0;T.x[1][1]=0;
    pow(n-1);
    if(d!=b2&&n%2==0) f=1;
    T.x[0][0]=(T.x[0][0]-f+mod)%mod;
    cout<<T.x[0][0]<<endl;
    return 0;
}

  

  

This passage is made by Iscream-2001.

 

posted @ 2017-11-07 18:59  Iscream-2001  阅读(172)  评论(0编辑  收藏  举报
/* */