Reading comprehension(HDU-4990)

Problem Description

Read the program below carefully then answer the question. 

#pragma comment(linker, "/STACK:1024000000,1024000000") 
#include <cstdio> 
#include<iostream> 
#include <cstring> 
#include <cmath> 
#include <algorithm> 
#include<vector> 
const int MAX=100000*2; 
const int INF=1e9; 
int main() 
{ 
  int n,m,ans,i; 
  while(scanf("%d%d",&n,&m)!=EOF) 
  { 
    ans=0; 
    for(i=1;i<=n;i++) 
    { 
      if(i&1)ans=(ans*2+1)%m; 
      else ans=ans*2%m; 
    } 
    printf("%d\n",ans); 
  } 
  return 0; 
}

Input

Multi test cases,each line will contain two integers n and m. Process to end of file. 
[Technical Specification] 
1<=n, m <= 1000000000

Output

For each case,output an integer,represents the output of above program.

Sample Input

1 10
3 100

Sample Output

1
5

题意:根据,输入 n、m 给出结果

思路:

n、m 数据范围能到1E9,直接暴力一定会 TLE

分析一下代码中的递推公式:

  • n 为奇数时:f[n] = f[n-1] * 2 + 1
  • n 为偶数时:f[n] = f[n-1] * 2

假设 n 为奇数,那么 f[n] = f[n-1] * 2 + 1,得到的 n-1 必定是偶数

于是有:f[n] = f[n-1] + f[n-2] * 2 + 1

同理,假设 n 为偶数,那么 f[n] = f[n-1] * 2,得到的 n-1 必定是奇数

于是有:f[n] = f[n-1]+ f[n-2] * 2+1

那么,无论 n 为奇还是为偶,f[n] = f[n-1]+ f[n-2] * 2+1 一定成立

根据公式构造矩阵:\begin{bmatrix}f(n) \\ f(n-1) \\ 1 \end{bmatrix}= \begin{bmatrix} 1 &2 &1 \\ 1&0 &0 \\ 0 &0 &1 \end{bmatrix} \begin{bmatrix}f(n-1) \\ f(n-2) \\ 1 \end{bmatrix}

化简后:\begin{bmatrix}f(n) \\ f(n-1) \\ 1 \end{bmatrix}= \begin{bmatrix} 1 &2 &1 \\ 1&0 &0 \\ 0 &0 &1 \end{bmatrix}^{n-1} \begin{bmatrix}f(1) \\ f(0) \\ 1 \end{bmatrix}

由于 f(0)=0,f(1)=1,那么有:\begin{bmatrix}f(n) \\ f(n-1) \\ 1 \end{bmatrix}= \begin{bmatrix} 1 &2 &1 \\ 1&0 &0 \\ 0 &0 &1 \end{bmatrix}^{n-1} \begin{bmatrix}1 \\ 0 \\ 1 \end{bmatrix}

故答案为:f(n)=A[1][1]*1+A[1][2]*0+A[1][3]*1=A[1][1]+A[1][3]

因此矩阵快速幂求出 A 后即得答案

Source Program

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define PI acos(-1.0)
#define E 1e-9
#define INF 0x3f3f3f3f
#define LL long long
const int MOD=10000007;
const int N=10+5;
const int dx[]= {-1,1,0,0};
const int dy[]= {0,0,-1,1};
using namespace std;
struct Matrix{
    LL s[N][N];
};
Matrix e;//单位矩阵E
Matrix x;//构造矩阵
LL n,m;
void init(){
    for(int i=1;i<=3;i++)//主对角线为1
        e.s[i][i]=1;

    //构造矩阵
    x.s[1][1]=1L;x.s[1][2]=2L;x.s[1][3]=1L;
    x.s[2][1]=1L;x.s[2][2]=0L;x.s[2][3]=0L;
    x.s[3][1]=0L;x.s[3][2]=0L;x.s[3][3]=1L;
}
Matrix mul(Matrix A,Matrix B){//矩阵乘法,n代表A、B两个矩阵是n阶方阵
    Matrix temp;//临时矩阵,存放A*B结果

    for(int i=1;i<=3;i++)
        for(int j=1;j<=3;j++)
            temp.s[i][j]=0;

    for(int i=1;i<=3;i++)
        for(int j=1;j<=3;j++)
            for(int k=1;k<=3;k++)
                temp.s[i][j]=(temp.s[i][j]+(A.s[i][k]*B.s[k][j])%m)%m;
    return temp;
}
Matrix quickPower(Matrix a,LL b){//矩阵快速幂,求矩阵n阶矩阵的b次幂
    Matrix ans=e;
    while(b){
        if(b&1)
            ans=mul(ans,a);//ans=e*a
        a=mul(a,a);//a=a*a
        b>>=1;
    }
    return ans;
}
int main(){
    init();
    while(scanf("%lld%lld",&n,&m)!=EOF&&(n+m)){
        Matrix res=quickPower(x,(LL)(n-1));
        printf("%lld\n",(res.s[1][1]+res.s[1][3])%m);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值