hdu 4990 Reading comprehension(矩阵快速幂)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37868325/article/details/88843200

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的值,比较裸的矩阵快速幂

a[1]=1;

a[2]=a[1]*2;     a[3]=a[2]*2+1=a[1]*4+1;

a[4]=a[3]*2;      a[5]=a[4]*2+1=a[3]*4+1;

a[6]=a[5]*2;      a[7]=a[6]*2+1=a[5]*4+1;

所以很容易推出关系矩阵\begin{pmatrix} a_{i} &1 \\ a_{i-1} &1 \end{pmatrix} =\begin{pmatrix} a_{i-1} &1 \\ a_{i-2} &1 \end{pmatrix} *\begin{pmatrix} 4&0 \\ 1&1 \end{pmatrix},一直带下去\begin{pmatrix} a_{n} &1 \\ a_{n-1} &1 \end{pmatrix} =\begin{pmatrix} 1 &1 \\ 0 &1 \end{pmatrix} *\begin{pmatrix} 4&0 \\ 1&1 \end{pmatrix}^{n/2+n%2-1}}\left (*(n%2?1:2) \right )*(n%2?1:2)

代码:(自己手搓的板子,开心o(* ̄▽ ̄*)ブ)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 15
ll n,mod;
///n行m列的矩阵
struct AA
{
    ll n,m,a[maxn][maxn];
    void mem1()
    {
        memset(a,0,sizeof(a));///n=m时,初始化为单位阵
        for(int i=0;i<n;i++)
            a[i][i]=1;
    }
};

///n行m列的aa矩阵 * m行k列的bb矩阵
AA mul(AA aa,AA bb,int n,int m,int k)
{
    AA cc;
    cc.n=n;cc.m=k;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<k;j++)
        {
            int x=0;
            for(int k=0;k<m;k++)
            {
                x+=aa.a[i][k]*bb.a[k][j]%mod;
                x%=mod;
            }
            cc.a[i][j]=x;
        }
    }
    return cc;
}

///方阵aa的m次方
AA POW(AA aa,int m)
{
    AA d;d.n=d.m=aa.n;
    d.mem1();
    while(m)
    {
        if(m&1)
        {
            d=mul(d,aa,d.n,d.m,aa.m);
        }
        m/=2;
        aa=mul(aa,aa,aa.n,aa.n,aa.n);
    }
    return d;
}
int main()
{
    ll cnt=0;
    while(~scanf("%lld%lld",&n,&mod))
    {
        AA aa,bb;
        aa.n=2;aa.m=2;
        aa.a[0][0]=1;
        aa.a[0][1]=1;
        aa.a[1][0]=0;
        aa.a[1][1]=1;
        bb.n=bb.m=2;
        bb.a[0][0]=4;
        bb.a[0][1]=0;
        bb.a[1][0]=1;
        bb.a[1][1]=1;

        AA cc=mul(aa,POW(bb,(n/2)+(n%2)-1),2,2,2);

        printf("%lld\n",n%2?cc.a[0][0]:cc.a[0][0]*2%mod);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37868325/article/details/88843200