矩阵练习

HDU4549  M斐波那契数列(矩阵快速幂+欧拉定理)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4549

中文题目读起来就是爽啊,常规做了一遍,妥妥超时了,看那个a,b的指数满足斐波那契数列,所以用矩阵来构造。然后在WA了很多遍找不到错误的情况下,后来看了下网上的题解,才知道在做矩阵乘法的时候即使用long long也有可能溢出~题目要求对10000000007取模,是个质数。A^B%C,且C为质数,A,C互质,利用数论的知识可以得到:

A^B%C=A^(B%(C-1))%C;


代码:

#include 
#include 
#define mod 1000000007
#define Max_dimension 2
typedef long long LL;

typedef LL Matrix[Max_dimension][Max_dimension];
int ndim=Max_dimension;

Matrix A={{1,1},{1,0}};
void m_zero(Matrix x)
{
    memset(x,0,sizeof(LL)*Max_dimension*Max_dimension);
}
void m_one(Matrix x)
{
    m_zero(x);
    for(int i=0;i>=1)
        {
            m_multiple(temp_x,temp_x,temp);
            m_copy(temp,temp_x);
        }
    }

}

LL quick_pow(LL t,LL m)
{
    LL tmp=t%mod;
    LL ant=1;
    while(m)
    {
        if(m&1)
        {
            ant*=tmp;
            ant%=mod;
        }
        m>>=1;
        tmp*=tmp;
        tmp%=mod;
    }
    return ant;
}


//Matrix B={{1},{2}};
int main()
{
    //freopen("in.txt","r",stdin);
     
    int a,b,n;
    Matrix ans;
    while(scanf("%d%d%d",&a,&b,&n)!=EOF)
    {
		m_zero(ans);
        if(n)
            m_pow(A,n-1,ans);
        else
        {
            ans[0][0]=0;
            ans[1][0]=1;
        }
        //m_multiple(ans,B,res); //b的次幂

        LL num1=quick_pow(b,ans[0][0])%mod;
        LL num2=quick_pow(a,ans[1][0])%mod;
        printf("%d\n",num1*num2%mod);
    }
    return 0;
}

/*
100 10 3
10 10 5
*/


HDU2254 奥运

链接:http://acm.hdu.edu.cn/showproblem.php?pid=2254

如果能够想到用矩阵的话,这道题目就不难做,求两个城市之间的走法,在限制时间内达到,矩阵幂之和即可·····用STL的map来保存每个点·····

代码:

#include 
#include 
#include 
#include 
using namespace std;

#define mod 2008
#define size 30

int ndim;
struct Matrix
{
    int a[size][size];
}tem;


Matrix m_one(Matrix x)
{
    for(int i=0;i<30;i++)
        for(int j=0;j<30;j++)
            if(i==j)
                x.a[i][j]=1;
            else
                x.a[i][j]=0;
    return x;
}

Matrix m_add(Matrix a,Matrix b)
{
    Matrix c;
    for(int i=0;i>=1;
    }

    return x;
}

Matrix m_pow_sum(Matrix x,int p)
{
    //Matrix tem;
    if(p==1)
        return x;
    else if(p&1)
        return m_add(m_pow(x,p),m_pow_sum(x,p-1));
    else
        return m_multiple(m_pow_sum(x,p>>1),m_add(m_pow(x,p>>1),tem));
}


int main()
{
    int T,n,k,t1,t2,v1,v2;
    int x,y,num;
    map mapp;
    Matrix res,s1,s2;
    tem=m_one(tem);

    while(scanf("%d",&T)!=EOF)
    {
        for(int i=0;i<30;i++)
            for(int j=0;j<30;j++)
                res.a[i][j]=0;

        num=0;
        mapp.clear();
        while(T--)
        {
            scanf("%d%d",&x,&y);
            if(!mapp.count(x))
                mapp[x]=num++;
            if(!mapp.count(y))
                mapp[y]=num++;

            res.a[mapp[x]][mapp[y]]++;  //记录这两点之间有几种走法
        }

        ndim=num;
        scanf("%d",&k);
        while(k--)
        {
            scanf("%d%d%d%d",&v1,&v2,&t1,&t2);
          
            if(t21)
          {
              s1=m_pow_sum(r,t1-1);
              p1=s1.a[mapp[v1]][mapp[v2]];
          }
          if(t2>=1)
          {
              s2=m_pow_sum(r,t2);
              p2=s2.a[mapp[v1]][mapp[v2]];
          }
          printf("%d\n",(p2-p1+mod)%mod);
        }
    }

    return 0;
}

HDU2604 Queuing

链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604

题意:用m和f来随机排列,但是不可以出现fmf和fff的形式,问有多少种方式

分析:f(n)表示n个人的排列方法···这样考虑:

如果前边的人都符合题意,那么f(n)就是f(n-1)在增添一个人,但是不能出现那两种形式。想象f(n-1)是合法的,再增添一个m是合法的,有f(n-1)种····

但是如果最后一个人是m,则f(n-1)可以是f或者m结尾,则要看f(n-2),但是这ff和mf都不能直接确定是不是合法,再向前看一个,即f(n-3),就有4种形式了,mm,mf,fm,ff分别和f组合,fm,ff显然不合法,去掉。mmf无限制,f(n-3)种···

还剩一个mf,仅看f(n-3)是无法看出能不能放,再向前看一个,即f(n-4),mmff是无限制的,所以f(n-4)种

综上:f(n)=f(n-1)+f(n-3)+f(n-4)

置于矩阵呢,很好构造,

 A={{1,0,1,1},{1,0,0,0},{0,1,0,0,},{0,0,1,0}}
代码:
#include 
#include 
#include 
#define Max_dimension 4
//#define mod 2008

typedef int Matrix_type;
typedef long long  Max_int_type;
typedef Matrix_type Matrix[Max_dimension][Max_dimension];

int mod;
int ndim=Max_dimension;
void m_zero(Matrix x)
{
    memset(x,0,sizeof(Matrix_type)*Max_dimension*Max_dimension);
}

void m_one(Matrix x)
{
    m_zero(x);
    for(int i=0;i>= 1)
        {
            m_multiple(temp_x,temp_x,temp);
            m_copy(temp,temp_x);
        }
    }
}

Matrix A={{1,0,1,1},{1,0,0,0},{0,1,0,0,},{0,0,1,0}};
Matrix B={{9},{6},{4},{2}};
int main()
{
     //freopen("in.txt","r",stdin);
     Matrix ans,sum;
     int l;
     while(scanf("%d%d",&l,&mod)!=EOF)
     {
           if(l==0)
           {
            printf("0\n");
            continue;
           }
           if(l==1)
           {
                 printf("%d\n",2%mod);
                 continue;
           }
           if(l==2)
           {
                 printf("%d\n",4%mod);
                 continue;
           }
           if(l==3)
           {
                 printf("%d\n",6%mod);
                 continue;
           }
           if(l==4)
           {
                 printf("%d\n",9%mod);
                 continue;
           }

           m_pow(A,l-4,ans);
           m_multiple(ans,B,sum);
           printf("%d\n",sum[0][0]%mod);

     }
     return 0;
}




      

你可能感兴趣的:(矩阵)